经过前几天对线性表的学习,用几道算法题对线性表的此次学习进行收尾。每一个人的思惟方式不一样,写的算法代码也不一样。如下的相关代码,是本人感受思路比较清晰简洁的方式。如你有本身的想法,能够本身尝试一下,但愿能够将你的方式分享出来给我,谢谢!算法
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; } 复制代码
线性表告一段落,接下来还会继续学习数据结构相关知识。继续享受学习过程的快乐。记住:沿途的风景要比目的地更弯的否!!!数组