資料結構:陣列
阿新 • • 發佈:2018-12-17
陣列和字串是兩種最基本的資料結構,陣列佔據一塊連續的記憶體並按照順序儲存資料。建立陣列時,我們需要首先指定陣列的容量大小,然後根據大小分配記憶體,因此陣列的空間效率不是很好,會有空閒的區域,導致記憶體浪費。 1.陣列與雜湊表 因為陣列中的記憶體是連續的,根據下標讀寫元素,它的效率比較高,我們可以利用陣列的時間效率高的特點去實現簡單的雜湊表:把陣列的下標設為雜湊表的鍵值,陣列中存放的值設為雜湊表的值。 2.動態陣列 為了避免浪費,設計了多種動態陣列,先為陣列開闢較小的空間。當資料的數目超出陣列的容量時,我們再重新分配一塊更大的空間。並把之前的資料複製到新記憶體中,把之前的記憶體釋放,這樣能減少記憶體浪費。但是每一次動態擴充是都會有很多的額外操作,這對時間效能不利,因此動態陣列要儘量減少改變陣列容量大小的次數。 3.陣列與指標 sizeof(指標)大小恆定為4,sizeof(陣列)是求陣列的大小。 當陣列作為函式引數進行傳遞時,陣列就會自動退化為同類型的指標。
//=========劍指offer第二版面試題50=============== //字串中第一隻出現一次的字元 //在字串中找出第一個只出現一次的字元,如輸入“abaccdeff”,則輸出‘b’ /*解題思路:在本題中我們只需要利用一個簡單的雜湊表,字元是一個長度為(0-255)*/ # include <stdio.h> # include <string.h> char FirstNotRepeatingChar(char * pString) { if(pString == NULL) { return '\0'; } const int size = 256; int array[size]; for(int i=0;i<size;i++) { array[i]=0; } char *p = pString; while (*p!='\0') { array[*p++]++; } p=pString; while(*p!='\0') { if(array[*p]==1) { return *p; } p++; } return '\0'; } //==========測試用例======== void Test(char *pString,char key) { if(FirstNotRepeatingChar(pString) == key) printf("Test passed.\n"); else printf("Test failed.\n"); } int main() { // 存在只出現一次的字元 Test("google", 'l'); // 不存在只出現一次的字元 Test("aabccdbd", '\0'); // 所有字元都只出現一次 Test("abcdefg", 'a'); // 輸入nullptr Test(nullptr, '\0'); return 0; }
輸出結果為: Test passed. Test passed. Test passed. Test passed. 請按任意鍵繼續. . .
//===========劍指offer第二版面試題3======== //題目一:找出陣列中重複的數字 /*解題思路:1.先把這個陣列進行排序,從排序好的陣列中從頭到尾遍歷一遍找到重複的數字時間複雜度為O(nlogn) 2.利用雜湊表來解決,需要申請一個空間為n的雜湊表,以空間換時間 3.重排這個陣列,從頭到尾掃描這個陣列,當掃描到下標為i時,首先比較這個數字m是不是等於i,如果是則繼續掃描如果不是,再拿他跟m下標下的數字 進行比較,如果它跟m下標所存放的數字相等,則找到一個重複數字,如果不相等,就把這個數與m下標的數進行互換,繼續比較,直到發現一個重複數字。 */ # include <stdio.h> bool duplicate(int arr[],int length,int *duplicate) { if(arr == NULL || length <=0)//先排除不符合條件的情況 { return false; } for(int i=0;i<length-1;i++) { if(arr[i]<0||arr[i]>length-1) { return false; } } for(int i=0;i<length-1;i++) { while(arr[i]!=i) { if(arr[arr[i]]==arr[i])//如果該元素與m位置元素相同,則找到了一個重複數字 { *duplicate = arr[i]; return true; } //交換該元素與m位置元素 int temp = arr[i]; arr[i]=arr[arr[i]]; arr[temp]=temp;//注意在這裡犯錯為了!!第一次錯寫為arr[arr[i]],此時會陷入死迴圈 } } return false;//直到整個陣列遍歷完,表示還沒找到,返回false } //==========測試用例=========== bool contains(int array[], int length, int number) { for(int i = 0; i < length; ++i) { if(array[i] == number) return true; } return false; } void test(char* testName, int numbers[], int lengthNumbers, int expected[], int expectedExpected, bool validArgument) { printf("%s begins: ", testName); int duplication; bool validInput = duplicate(numbers, lengthNumbers, &duplication); if(validArgument == validInput) { if(validArgument) { if(contains(expected, expectedExpected, duplication)) printf("Passed.\n"); else printf("FAILED.\n"); } else printf("Passed.\n"); } else printf("FAILED.\n"); } // 重複的數字是陣列中最小的數字 void test1() { int numbers[] = { 2, 1, 3, 1, 4 }; int duplications[] = { 1 }; test("Test1", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true); } // 重複的數字是陣列中最大的數字 void test2() { int numbers[] = { 2, 4, 3, 1, 4 }; int duplications[] = { 4 }; test("Test2", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true); } // 陣列中存在多個重複的數字 void test3() { int numbers[] = { 2, 4, 2, 1, 4 }; int duplications[] = { 2, 4 }; test("Test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true); } // 沒有重複的數字 void test4() { int numbers[] = { 2, 1, 3, 0, 4 }; int duplications[] = { -1 }; // not in use in the test function test("Test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false); } // 沒有重複的數字 void test5() { int numbers[] = { 2, 1, 3, 5, 4 }; int duplications[] = { -1 }; // not in use in the test function test("Test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false); } // 無效的輸入 void test6() { int* numbers = NULL; int duplications[] = { -1 }; // not in use in the test function test("Test6", numbers, 0, duplications, sizeof(duplications) / sizeof(int), false); } int main() { test1(); test2(); test3(); test4(); test5(); test6(); return 0; }
輸出結果為: Test1 begins: Passed. Test2 begins: Passed. Test3 begins: Passed. Test4 begins: Passed. Test5 begins: Passed. Test6 begins: Passed. 請按任意鍵繼續. . .