經過前幾天對線性表的學習,用幾道算法題對線性表的此次學習進行收尾。每一個人的思惟方式不一樣,寫的算法代碼也不一樣。如下的相關代碼,是本人感受思路比較清晰簡潔的方式。如你有本身的想法,能夠本身嘗試一下,但願能夠將你的方式分享出來給我,謝謝!算法
Status mergeOrderedLists(LinkList *list1, LinkList *list2, LinkList *list3) { LinkList p1 = (*list1)->next; LinkList p2 = (*list2)->next; LinkList p3 = *list1; *list3 = p3; LinkList temp; //循環遍歷兩個列表 while (p1 && p2) { if (p1->data < p2->data) {//若是鏈表1中的結點data小於鏈表2中結點data,鏈表1結點插入到鏈表3中 p3->next = p1; p3 = p1; p1 = p1->next; } else if (p1->data > p2->data) {//若是鏈表1中的結點data大於鏈表2中結點data,鏈表2結點插入到鏈表3中 p3->next = p2; p3 = p2; p2 = p2->next; } else {//若是鏈表1中的結點data等於鏈表2中結點data,保留鏈表1的結點,free鏈表2的結點 p3->next = p1; p3 = p1; p1 = p1->next; temp = p2->next; free(p2); p2 = temp; } } //退出循環的條件是鏈表1或者鏈表2同時指向NULL或者其中一個指向NULL,用一個三則運算符,把剩下的結點插入到鏈表3中。 p3->next = p1?p1:p2; free(*list2); return OK; } int main(int argc, const char * argv[]) { // insert code here... printf("Hello, World!\n"); LinkList list1; LinkList list2; createList(&list1); createList(&list2); for (int i = 1; i < 10; i += 2) { insertValue(&list1, i); } insertValue(&list2, 1); insertValue(&list2, 2); insertValue(&list2, 3); insertValue(&list2, 4); printf("list1:"); displayList(list1); printf("\n"); printf("list2:"); displayList(list2); printf("\n"); LinkList list3; mergeOrderedLists(&list1, &list2, &list3); displayList(list3); return 0; } 複製代碼
Status orderedListIntersection(LinkList *list1, LinkList *list2, LinkList *list3) { LinkList p1 = (*list1)->next; LinkList p2 = (*list2)->next; LinkList p3 = *list1; *list3 = p3; LinkList temp; while (p1 && p2) { if (p1->data == p2->data) {//相等,把p1加入的list3中,釋放p2。p1和p2都往下指向 p3->next = p1; p3 = p1; p1 = p1->next; temp = p2->next; free(p2); p2 = temp; } else if (p1->data < p2->data){//p1小,釋放p1,p1向下指向 temp = p1->next; free(p1); p1 = temp; } else {//p2小,釋放p2,p2向下指向 temp = p2->next; free(p2); p2 = temp; } } while (p1) {//p1後面還有結點,循環刪除 temp = p1->next; free(p1); p1 = temp; } while (p2) {//p2後面還有結點,循環刪除 temp = p2->next; free(p2); p2 = temp; } //p3鏈表結尾設爲NULL p3->next = NULL; free(*list2); return OK; } int main(int argc, const char * argv[]) { LinkList list1; LinkList list2; createList(&list1); insertValue(&list1, 1); insertValue(&list1, 2); insertValue(&list1, 3); insertValue(&list1, 4); insertValue(&list1, 5); insertValue(&list1, 6); insertValue(&list1, 7); insertValue(&list1, 8); insertValue(&list1, 9); printf("list1\n"); displayList(list1); createList(&list2); insertValue(&list2, 2); insertValue(&list2, 4); insertValue(&list2, 6); insertValue(&list2, 8); insertValue(&list2, 10); printf("list2\n"); displayList(list2); LinkList list3; orderedListIntersection(&list1, &list2, &list3); printf("list3\n"); displayList(list3); return 0; } 複製代碼
Status listReverseOrder(LinkList *list) { LinkList p = (*list)->next; LinkList q; (*list)->next = NULL; while (p) { q = p->next; p->next = (*list)->next; (*list)->next = p; p = q; } return OK; } int main(int argc, const char * argv[]) { LinkList list; createList(&list); for (int i = 0; i <= 10; i+=2) { insertValue(&list, i); } displayList(list); listReverseOrder(&list); displayList(list); return 0; } 複製代碼
Status OrderedListDelElemByRange(LinkList *list, ElemType min, ElemType max) { if (*list == NULL) { return ERROR; } LinkList p = (*list)->next; LinkList low = NULL, high = NULL; //找到小於min的結點的前一個結點low while (p && p->data < min) { low = p; p = p->next; } //找到小於等於max的結點high while (p && p->data <= max) { p = p->next; } high = p; //原鏈表剔除low->next到high之間的結點 low->next = high; //刪除low->next到high之間的結點 LinkList temp; while (low != high) { temp = low->next; free(low); low = temp; } return OK; } int main(int argc, const char * argv[]) { LinkList list; createList(&list); for (int i = 1; i < 100; i++) { insertValue(&list, i); } displayList(list); OrderedListDelElemByRange(&list, 8, 24); displayList(list); return 0; } 複製代碼
void reverse(int *arr,int left ,int right){ int low = left; int high = right; while (low < high) { arr[low] ^= arr[high] ^= arr[low] ^= arr[high]; low ++; high --; } } void leftShift(int *arr, int n, int p){ if (p > 0 && p < n) { //總體翻轉 reverse(arr, 0, n - 1); //翻轉分割點前面部分 reverse(arr, 0, n - p - 1); //翻轉分割點後面部分 reverse(arr, n-p, n-1); } } int main(int argc, const char * argv[]) { int arr[10] = {0,1,2,3,4,5,6,7,8,9}; for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); } printf("\n"); leftShift(arr, 10, 3); for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } 複製代碼
int getMainElement(int *arr, int n){ //把第一個元素當作候選主元素 int key = arr[0]; int count = 1; for (int i = 1; i < n; i++) { if (key == arr[i]) { count ++; } else { if (count > 0) { count --; } else { key = arr[i]; count = 1; } } } //count > 0 ,統計候選主元素出現的次數,用count表示 if (count > 0) { for (int i = count = 0; i < n; i++) { if (arr[i] == key) { count ++; } } } //判斷count是否知足大於數組一半的要求 if (count > n / 2) { return key; } else { return -1; } } int main(int argc, const char * argv[]) { int a[] = {0,5,5,3,5,7,5,5}; int b[] = {0,5,5,3,5,1,5,7}; int c[] = {0,1,2,3,4,5,6,7}; for (int i = 0; i < 8; i++) { printf("%d ", a[i]); } printf("\n"); int value = getMainElement(a, 8); printf("value = %d \n", value); value = getMainElement(b, 8); printf("value = %d \n", value); value = getMainElement(c, 8); printf("value = %d \n", value); return 0; } 複製代碼
void listDelRepeatElem(LinkList *list,int n){ //開闢輔助數組 int *arr = alloca(sizeof(int)*n); for (int i = 0; i < n; i++) { *(arr+i) = 0; } LinkList p = (*list)->next; LinkList temp = *list; //遍歷鏈表 while (p) { //若是該絕對值已經在結點上出現過,則刪除該結點 if (arr[abs(p->data)] == 1) { temp->next = p->next; free(p); p = temp->next; } else {//未出現過的結點,則將數組中對應位置置爲1 arr[abs(p->data)] = 1; temp = p; p = p->next; } } } int main(int argc, const char * argv[]) { // insert code here... printf("Hello, World!\n"); LinkList list; createList(&list); insertValue(&list, 21); insertValue(&list, -15); insertValue(&list, 15); insertValue(&list, -7); insertValue(&list, 15); displayList(list); listDelRepeatElem(&list, 21); displayList(list); return 0; } 複製代碼
線性表告一段落,接下來還會繼續學習數據結構相關知識。繼續享受學習過程的快樂。記住:沿途的風景要比目的地更彎的否!!!數組