/*
*author:y
*/#include<stdio.h>#include<stdlib.h>#include<malloc.h>#include<time.h>#include<windows.h>typedefstructnode{int data;structnode* next;}NODE,* LinkList;//创建带头节点的单链表,并赋值十个随机数
LinkList createListWithHead(LinkList L){int i, num =10;
LinkList p;
L =(NODE*)malloc(sizeof(NODE));
L->next =NULL;//初始化头节点
p = L->next;for(i =0; i < num; i++)//随机生成10个数据{
LinkList temp =(NODE*)malloc(sizeof(NODE));//创建新元素的节点空间
temp->data =rand()%101;//新节点赋值100以内的随机数
temp->next = p;
L->next = temp;
p = temp;}return L;}//遍历链表voidreverse(LinkList L){
LinkList p = L;
p = p->next;while(p !=NULL){printf("%d ", p->data);
p = p->next;}printf("\n");}//通过输入的数值去表中查找该值是否在表中,若找到该值返回其表中位置,反之返回0intfindListByVal(LinkList L,int v){
LinkList p;int i =1;
p = L->next;while(p !=NULL)//当节点为空时停止循环{if(p->data == v)return i;//该值存在退出循环返回其位置
i++;
p = p->next;}return-1;}//通过输入的位置去表中查找该位置的值
LinkList findListByPos(LinkList L,int k){
LinkList p;int i =1;
p = L->next;while(p && i < k){
p = p->next;
i++;}if(p && i == k)return p;returnNULL;}/*单链表插入运算
* 将元素newElem插入表中的第k个元素之前,若成功则返回0,否则返回-1
*/intinsertList(LinkList L,int k,int newElem){
LinkList p, s;if(k ==1)p = L;//插入位置为1,直接将元素newElem插入到第1个元素之前else p =findListByPos(L, k -1);//查找表中的第k-1个元素并令p指向该元素节点if(!p)return-1;//表中不存在k-1个元素,不满足运算直接退出
s =(NODE*)malloc(sizeof(NODE));//创建新元素的节点空间if(!s)return-1;
s->data = newElem;
s->next = p->next;
p->next = s;//将元素newELem插入第k-1个元素之后return0;}/*单链表删除运算
*删除表中的第k个元素节点,若成功则返回0,否则返回-1
*/intdeleteList(LinkList L,int k){
LinkList p, q;if(k ==1)p = L;//删除第一个元素节点else p =findListByPos(L, k -1);//查找表中的第k-1个元素并令p指向该元素节点if(!p ||!p->next)return-1;//表中不存在第k个元素
q = p->next;//令q指向第k个元素节点
p->next = q->next;free(q);//删除节点return0;}/*------------------------------------------
*归并排序
*采用分治和递归的思想
*先将链表的元素进行逐层折半分组直至分为单个有序的节点,再从最小的分组开始比较排序
*以升序为例将较大的元素合并在较小元素之后,逐层进行比较排序合并。最终合并成一个大而有序的组合。
*/
LinkList mergeList(LinkList L1, LinkList L2){//当L1|L2链表没有元素需要组合后继续L2|L1的链表组合if(L1 ==NULL){return L2;}if(L2 ==NULL){return L1;}//用于存储新链表的头节点指针
LinkList head;//小的值链接到下一个if(L1->data < L2->data)//左半边组合的第一个剩余元素更小{
head = L1;
head->next =mergeList(L1->next, L2);//继续排序组合L1->next,和L2的元素大小}else//右半边组合的第一个剩余元素更小{
head = L2;
head->next =mergeList(L1, L2->next);}return head;}
LinkList sortList(LinkList headref){if(headref ==NULL|| headref->next ==NULL){return headref;}//定义三个指针分别指向链表的0、1、2位地址
LinkList slow = headref, mid = headref->next, fast = headref->next->next;//通过循环使fast指针走到尾时,取到中间节点的前一个节点while(fast && fast->next){
slow = slow->next;
mid = mid->next;
fast = fast->next->next;}//将链表一分为二,[slow,mid)为左半边链表组合,[mid,fas)为右半边链表组合
slow->next =NULL;//通过递归不断切割左边的组合直至只剩单个有序元素
LinkList node1 =sortList(headref);//通过递归不断切割右边的组合直至只剩单个有序元素
LinkList node2 =sortList(mid);//重组新的有序链表组合
LinkList newList =mergeList(node1, node2);return newList;}/*------------------------------------------*/voidcheckEnter(int f,int num){if(f ==0)return;//正常退出if(f ==-1){printf("Please check your enter !!!\n");//异常退出return;}if(f >0)//查找返回printf("%d is in the %d position in the list \n", num, f);}voidq1(LinkList L1){int num, pos;printf("-------------- Question 01 Operation of a singly linked list ---------------\n");printf("There are 10 numbers in the list: \n");reverse(L1);//根据用户输入的数值查找该值是否在表中printf("Please enter the number you want to find: \n");scanf_s("%d",&num);checkEnter(findListByVal(L1, num), num);//根据用户输入的位置和值插入到表中printf("Please enter the postion and number you want to insert: \n");scanf_s("%d%d",&pos,&num);checkEnter(insertList(L1, pos, num),NULL);reverse(L1);//根据用户输入的位置删除表中该位置的值printf("Please enter the position of the number you want to delete: \n");scanf_s("%d",&pos);checkEnter(deleteList(L1, pos),NULL);reverse(L1);}voidq2(LinkList L1, LinkList L2){
LinkList L3 =NULL;printf("-------------- Question 02 Merge sort L1 and L2 ---------------\n");reverse(L1);reverse(L2);printf("---The following is sorted ones\n");sortList(L1);reverse(L1);sortList(L2);reverse(L2);printf("---The following is Merge sorted ones\n");
L3 =mergeList(L1, L2);reverse(L3->next);}voidmain(){
LinkList L1 =NULL, L2 =NULL;int opt, flag =1;srand(time(NULL));
L1 =createListWithHead(L1);
L2 =createListWithHead(L2);while(flag){system("cls");printf("[1] Check Q1 about Operation of a singly linked list\n");printf("[2] Check Q2 about Merge sort L1 and L2\n");printf("[0]--------Exit program-------- \n");scanf_s("%d",&opt);switch(opt){case0:flag =0;printf("See you next time ~\n");break;case1:q1(L1);break;case2:q2(L1, L2);break;default:printf("Please check your options!!!\n");break;}system("pause");}}