单向链表的相关操作总结:创建、删除、查找、排序、统计链表大小、链表的反转和遍历等
2015-07-09 17:49
901 查看
对单向链表的各种操作做了总结,并且考虑到了每个操作的特殊情况,对特殊情况也要求能够正确处理。
typedef struct link { struct link *next; int date; }Link,*List; //链表的创建 List init() { Link *st = malloc(sizeof(*st)); if(st == NULL ) { printf("Memory Erroy!\n"); return NULL; } else st->next = NULL; return st; } List creat() { Link *st = init(),*p; p = st; int k; while(p != NULL && scanf("%d",&k) != EOF) //默认EOF=-1,当scanf中输入ctrl+z时,返回值为-1 { Link *temp = malloc(sizeof(*temp)); //头节点为空, temp->date = k; temp->next = NULL; p->next = temp; p = p->next; } return st->next; //返回头结点的下一节点 } //判断链表是否为空 int linkempty(List st) { if(st == NULL) { printf("The one-way link is empty!\n"); return 0; } else return 1; } //统计链表元素个数 int linksize(List st) { int sum = 0; while(st != NULL) { sum++; st = st->next; } return sum; } //在顺序链表中插入元素,保持元素仍然有序 List orderinsert(List st,int k) { Link *head = malloc(sizeof(*head)); Link *pre,*p = head; pre = head; head->next = st; for(p = p->next;p != NULL;) { if(p->date > k) break; pre = p; p = p->next; } if(p == NULL) //链表中元素都不大于k { Link *tmp = malloc(sizeof(*tmp)); tmp->date = k; tmp->next = NULL; pre->next = tmp; } else { Link *tmp = malloc(sizeof(*tmp)); tmp->date = k; tmp->next = p; pre->next = tmp; } return head->next; } //在无序链表中的第i个位置后插入元素k List disorderinsert(List st,int i,int k) { int t = 0; Link *p = st,*pre; if(i == 0) //在头节点处插入 { printf("Insert to the head!\n"); Link *tmp = malloc(sizeof(*tmp)); tmp->date = k; tmp->next = p; st = tmp; } else { while(p != NULL && t < i) { t++; pre = p; p = p->next; } if(t <= i) { printf("Insert the new node to the tail!\n"); Link *tmp = malloc(sizeof(*tmp)); pre->next = tmp; tmp->date = k; tmp->next = NULL; } else { Link *tmp = malloc(sizeof(*tmp)); pre = p->next; p->next = tmp; tmp->date = k; tmp->next = pre; } } return st; } //删除元素k List datedelete(List st,int k) { Link *p, *pre = malloc(sizeof(*pre)); int t = 0; p = st; if(p->next == NULL) //链表为单节点链表 { if(p->date == k) printf("Signle node link and %d is root.\n",k); else printf("Signle node link and NO %d !\n",k); return NULL; } else { pre->next = st; st = pre; while(pre->next != NULL) { p = pre->next; if(p->date == k) { pre->next = p->next; free(p); t++; } else pre = p; } if(!t) printf(" NO %d!\n",k); return st->next; } } //在顺序链表中删除第i个最小元素 List locatedelete(List st,int i) { Link *p = st,*pre; int k,t = 1; k = p->date; pre = p->next; if(i == 1) //删除最小元素(从头节点开始删除) { free(p); p = pre; while(p != NULL && p->date == k) //考虑有多个相同元素(算一个等级,如:第一个最小)的情况 { pre = p->next; free(p); p = pre; } if(p == NULL) { printf("NULL!\n"); return NULL; } else return p; } else //删除第i个最小元素(i!=1,且第i个最小元素可能有多个) { p = p->next; while(p != NULL) { if(p->date != k) { t++; k = p->date; } if(t == i) break; else { pre = p; p = p->next; } } if(t < i) printf("The %dth min-date is NOT exist!\n",i); else { if(t == i) { pre->next = p->next; p = p->next; while(p != NULL && k == p->date) { pre->next = p->next; p = p->next; } } } return st; } } //查询元素k是否在链表中(0:链表中无此元素;否则元素存在) int datesearch(List st,int k) { Link *p = st; int i = 0; while(p != NULL) { if(p->date == k) i++; p = p->next; } return i; } //已知链表大小时寻找链表的中间元素 int middledateN(List st,int N) { int i = 1; if(N%2 == 0) { while(i != N/2) { i++; st = st->next; } return st->date; } else { while(i != N/2) { i++; st = st->next; } return st->next->date; } } //链表大小未知时,寻找中间元素 int middledate(List st) { Link *p,*mid; p = st; mid = st; //设置两个指针,mid为中间指针 while(p->next != NULL) { p = p->next; if(p->next != NULL) { p = p->next; mid = mid->next; } } return (mid->date); } //链表的反转 List linkreverse(List st) { if(st->next == NULL) { printf("Signle node link!\n"); return st; } else if(st->next->next == NULL) { printf("Only two nodes!\n"); Link *tmp = st->next; st->next->next = st; st->next = NULL; return tmp; } else { Link *pre, *p,*tmp; pre = NULL; p = st; while(p->next != NULL) { tmp = p->next; p->next = pre; pre = p; p = tmp; } p->next = pre; return p; } } //链表的遍历 void traverse(List st) { while(st != NULL) { printf("%3d",st->date); st = st->next; } printf("\n"); return; } //插入排序 List linkinsertsort(List st) { Link *p,*head = malloc(sizeof(*head)); Link *q; head->next = st; p = head; q = NULL; for(p = p->next;p != NULL;p = p->next) q = orderinsert(q,p->date); return q; } //将两个有序链表进行归并 List combine(List st1,List st2) { Link *st = malloc(sizeof(*st)); Link *p,*q,*head = st; p = st1; q = st2; while(p != NULL && p != NULL) { if(p->date < q->date) { st->next = p; st = p; p = p->next; } else { st->next = q; st = q; q = q->next; } } st->next = (p == NULL) ? q : p; return head->next; }
相关文章推荐
- 手斧Linux – 从LFS到Funtoo (143)
- 手斧Linux – 从LFS到Funtoo (142)
- POJ1236 Network of Schools 强连通+缩点
- Java基础之Format
- 自己的学习计划
- 怎么使用FMDB 第三方数据库
- 手斧Linux – 从LFS到Funtoo (141)
- MyBatis调用存储过程,含有返回结果集、return参数和output参数
- 【LeetCode】222. Count Complete Tree Nodes
- AR播放器
- 博客,我们是写给谁看的
- 图书馆管理系统(C++课程设计)
- https连接设置SSL协议和加密套件
- 自己写一个Raw方法
- 手斧Linux – 从LFS到Funtoo (140)
- 手斧Linux – 从LFS到Funtoo (139)
- Decision Tree 决策树 - ID3, C45, C50, CART...
- 使用Handler引发内存泄露的改进
- VisualStudio2010中创建ASP.Net WebService
- 手机移动端confirm替换方案