链表操作算法题合集
2015-01-18 10:08
197 查看
0.单链表的增、删、改、查(无头指针)
#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Insert(Node* First,int val) { Node* p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=First; First=p; return First; } Node* Node_Delete(Node* First,int val) { Node* p = First; Node* pre=NULL; Node* tem=NULL; int find=0; while(p!=NULL) { if(p->val==val) { pre->next=p->next; tem=p; p=pre->next; free(tem); } else { pre=p; p=p->next; } } return First; } Node* Node_Change(Node* First,int m,int n) { Node* p = First; while(p!=NULL) { if(p->val==m) { p->val=n; } p=p->next; } return First; } int Node_Search(Node* First,int x) { Node* p = First; int index=0; while(p!=NULL) { ++index; if(p->val==x) break; p=p->next; } if(p==NULL) index=-1; return index; } void order(Node* First) { Node* p=First; while(p!=NULL) { printf("%d ",p->val); p=p->next; } } int main() { int n,i,tem,tem2; while(printf("链表长度:")&&scanf("%d",&n)!=EOF) { getchar(); Node* First=NULL; printf("请插入链表:"); for(i=0;i<n;i++) { scanf("%d",&tem); First=Node_Insert(First,tem); } getchar(); printf("请输入删除的值:"); scanf("%d",&tem); getchar(); First=Node_Delete(First,tem); printf("删除后:\n"); order(First); printf("\n"); printf("请输入修改前和修改后的值:"); scanf("%d %d",&tem,&tem2); getchar(); First=Node_Change(First,tem,tem2); printf("修改后:\n"); order(First); printf("\n"); printf("请输入要查找的值:"); scanf("%d",&tem); getchar(); tem2=Node_Search(First,tem); if(tem2==-1) printf("没有这个数\n"); else printf("第%d个数\n",tem2); } return 0; }
1.单链表反转
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { if(pHead!=NULL) { ListNode * pre=NULL; ListNode * p=pHead; ListNode * q=pHead->next; while(q!=NULL) { p->next=pre; pre=p; p=q; q=q->next; } p->next=pre; return p; } return NULL; } };
2.找出单链表的倒数第n个元素
*p,*q 指向第一个指针,p向前移动n次,q再跟着和p一直移动,等p移到末尾,q所指的就是倒是第n个元素#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Insert(Node* First,int val) { Node* p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=First; First=p; return First; } void order(Node* First) { Node* p=First; while(p!=NULL) { printf("%d ",p->val); p=p->next; } } int My_Node_Search(Node* First,int n) { int i; Node* p,*q; q=p=First; if(First->next==NULL&&n==1) return 1; if(First->next==NULL&&n>1) return -1; if(n<=0) return -1; for(i=0;i<n;i++) { if(p==NULL) return -1; p=p->next; } while(p!=NULL) { p=p->next; q=q->next; } return q->val; } int main() { int n,i,tem; while(printf("链表长度:")&&scanf("%d",&n)!=EOF) { getchar(); Node* First=NULL; printf("请插入链表:"); for(i=0;i<n;i++) { scanf("%d",&tem); First=Node_Insert(First,tem); } getchar(); printf("链表为:"); order(First); printf("\n"); printf("取倒数第几个数:"); while(scanf("%d",&tem)!=EOF) { tem=My_Node_Search(First,tem); if(tem!=-1) printf("值为%d\n",tem); else printf("越界!\n"); printf("取倒数第几个数:"); } } return 0; }
3.找出单链表的中间元素(见0)
4.删除无头单链表的一个节点(见0)
5.两个不交叉的有序链表的合并
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { ListNode* p=pHead1; ListNode* q=pHead2; ListNode* First=NULL; ListNode* r=NULL; if (p == NULL ) return q; if (q == NULL ) return p; if(p->val<q->val) { r=p; p=p->next; } else { r=q; q=q->next; } First=r; while(p!=NULL&&q!=NULL) { if(p->val<q->val) { r->next=p; p=p->next; } else { r->next=q; q=q->next; } r=r->next; } while(p!=NULL) { r->next=p; r=r->next; p=p->next; } while(q!=NULL) { r->next=q; r=r->next; q=q->next; } r=NULL; return First; } };
6.判断单链表是否有环?
p1 p2 指向开头,p1的每次移动步长为1,p2的每次移动的步长为2。在p2==NULL前,如果出现p1==p2,则有环。#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Create(Node* p,int val) { p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=NULL; return p; } int If_Have_Circle(Node* First) { if( First==NULL) return 0; Node* p1=First; Node* p2=First; int Have=0; while(p1!=NULL&&p2!=NULL) { p1=p1->next; if(p1==NULL) break; p2=p2->next; if(p2==NULL) break; p2=p2->next; if(p2==NULL) break; if(p1==p2) { Have=1; break; } } return Have; } int main() { int i,tem; Node* No_Circle_First=NULL; Node* Have_Circle_First=NULL; Node* p=NULL; Node* q=NULL; q=Node_Create(q,1); p=q; No_Circle_First=q; q=Node_Create(q,2); p->next=q; p=p->next; q=Node_Create(q,3); p->next=q; p=p->next; q=Node_Create(q,4); p->next=q; q=Node_Create(q,1); p=q; Have_Circle_First=q; q=Node_Create(q,2); p->next=q; p=p->next; q=Node_Create(q,3); p->next=q; p=p->next; Node* index=p; q=Node_Create(q,4); p->next=q; p=p->next; q=Node_Create(q,5); p->next=q; p=p->next; p->next=index; int tem1=If_Have_Circle(No_Circle_First); printf("%s\n",tem1==0?"No":"Yes"); tem1=If_Have_Circle(Have_Circle_First); printf("%s\n",tem1==0?"No":"Yes"); return 0; }
7.判断两个单链表是否相交(见8)
8.两个单链表相交,计算相交点
先计算出两条链表的长度L1、L2,n=ans(L1-L2)。p1,p2分别指向两个链表的开头,指向长的链表的指针先向前移动n次,然后再两个一起移动。如果出现p1==p2,则开始计数。#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Create(Node* p,int val) { p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=NULL; return p; } void Find_Same(Node* First1,Node* First2) { int len1,len2,count; len1=len2=count=0; Node* p,*q; p=First1; while(p!=NULL) { ++len1; p=p->next; } p=First2; while(p!=NULL) { ++len2; p=p->next; } p=First1;q=First2; while(len1!=len2) { if(len1>len2) { p=p->next; ++len2; } else { q=q->next; ++len1; } } while(p!=q) { p=p->next; q=q->next; } while(p!=NULL) { ++count; printf("%d ",p->val); p=p->next; } printf("\n共%d个公共节点\n",count); } int main() { int i; Node* First1=NULL; Node* First2=NULL; Node* p=NULL; Node* q=NULL; q=Node_Create(q,1); p=q; First1=q; q=Node_Create(q,2); p->next=q; p=p->next; q=Node_Create(q,3); p->next=q; p=p->next; Node* index=p; q=Node_Create(q,4); p->next=q; q=Node_Create(q,1); p=q; First2=q; p->next=index; Find_Same(First1,First2); return 0; }
9.单链表排序
链表只能相邻改变,所以用冒泡排序最好。#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Insert(Node* First,int val) { Node* p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=First; First=p; return First; } void order(Node* First) { Node* p=First; while(p!=NULL) { printf("%d ",p->val); p=p->next; } } Node* Node_sort(Node* First) { if(First==NULL) return First; Node* p1,*p2,*pre; Node* rear=First; Node* L=(Node*)calloc(1,sizeof(Node)); L->next=First; while(rear->next!=NULL) rear=rear->next; while(rear!=First) { pre=L; p1=L->next; p2=L->next->next; while(p2!=rear->next&&p2!=NULL) { if(p1->val>p2->val) { pre->next=p1->next; p1->next=p2->next; p2->next=p1; pre=pre->next; p2=p1->next; } else { pre=pre->next; p1=p1->next; p2=p2->next; } } rear=pre; } return L->next; } int main() { int n,i,tem; while(printf("链表长度:")&&scanf("%d",&n)!=EOF) { getchar(); Node* First=NULL; printf("请插入链表:"); for(i=0;i<n;i++) { scanf("%d",&tem); First=Node_Insert(First,tem); } getchar(); printf("链表为:"); order(First); printf("\n"); First=Node_sort(First); printf("排序后为:"); order(First); printf("\n"); } return 0; }
10.删除单链表中重复的元素
用Hash数组保存各相同元素值的个数#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Insert(Node* First,int val) { Node* p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=First; First=p; return First; } void order(Node* First) { Node* p=First; while(p!=NULL) { printf("%d ",p->val); p=p->next; } } int cnt[101]; Node* Delete_Same(Node* First) { Node* p=First; Node* pre,*r; while(p!=NULL) { ++cnt[p->val]; p=p->next; } Node* L=(Node*)calloc(1,sizeof(Node)); L->next=First; pre=L; p=First; while(p!=NULL) { if(cnt[p->val]>1) { --cnt[p->val]; r=p; p=p->next; pre->next=p; free(r); } else { p=p->next; pre=pre->next; } } return L->next; } int main() { int n,i,tem,tem2; while(printf("链表长度:")&&scanf("%d",&n)!=EOF) { getchar(); Node* First=NULL; printf("请插入链表:"); for(i=0;i<n;i++) { scanf("%d",&tem); First=Node_Insert(First,tem); } printf("原链表:"); order(First); printf("\n"); for(i=0;i<101;i++) cnt[i]=0; First=Delete_Same(First); printf("删除后:"); order(First); printf("\n"); } return 0; }
11 链表拆分(将链表奇数位置上的节点构成一个新链表,偶数位置上的结点构成一个新链表)
#include <stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Insert(Node* First,int val) { Node* p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=First; First=p; return First; } void order(Node* First) { Node* p=First; while(p!=NULL) { printf("%d ",p->val); p=p->next; } } void Node_Cut(Node* First,Node* &First1,Node* &First2) { if(First==NULL) return; if(First->next==NULL) { First1=First; First1->next=NULL; return; } First1=First; First2=First->next; Node* p1=First1; Node* p2=First2; while(p1!=NULL&&p2!=NULL) { if(p1->next==NULL) break; if(p1->next->next==NULL) break; p1->next=p1->next->next; p1=p1->next; if(p2->next==NULL) break; if(p2->next->next==NULL) break; p2->next=p2->next->next; p2=p2->next; } p1->next=NULL; p2->next=NULL; } int main() { int n,i,tem,tem2; while(printf("链表长度:")&&scanf("%d",&n)!=EOF) { getchar(); Node* First=NULL; Node* First1=NULL; Node* First2=NULL; printf("请插入链表:"); for(i=0;i<n;i++) { scanf("%d",&tem); First=Node_Insert(First,tem); } printf("原链表:"); order(First); printf("\n"); Node_Cut(First,First1,First2); printf("拆分后:\n"); order(First1); printf("\n"); order(First2); printf("\n"); } return 0; }
12 大整数加法
#include<stdio.h> #include<stdlib.h> struct Node { int val; Node * next; }; Node* Node_Insert(Node* First,int val) { Node* p=(Node*)calloc(1,sizeof(Node)); p->val=val; p->next=First; First=p; return First; } void order(Node* First) { Node* p=First; while(p!=NULL) { printf("%d",p->val); p=p->next; } } int jinwei,tuiwei; Node* add1(Node* Long_Num,Node* Short_Num)// 同号整数相加 { Node* p1,*p2; p1=Long_Num;p2=Short_Num; while(p2!=NULL) { p1->val+=p2->val; p1=p1->next; p2=p2->next; } Node* p3=Long_Num; while(p3!=p1) { if(p3->val>=10) { if(p3->next==NULL) { jinwei=1;//进位 p3->val=p3->val%10; } else { p3->next->val+=p3->val/10; p3->val=p3->val%10; } } p3=p3->next; } return Long_Num; } Node* add2(Node* Long_Num,Node* Short_Num)//异号相加 { Node* p1,*p2; p1=Long_Num;p2=Short_Num; while(p2!=NULL) { p1->val-=p2->val; p1=p1->next; p2=p2->next; } Node* p3=Long_Num; while(p3!=p1) { if(p3->val<0) { --p3->next->val; p3->val+=10; } p3=p3->next; } return Long_Num; } int My_Compare(Node* Num1,Node* Num2) { Node* p1,*p2; p1=Num1; p2=Num2; while(p1!=NULL) { if(p1->val>p2->val) return 1; if(p1->val<p2->val) return -1; p1=p1->next; p2=p2->next; } return 0; } Node* Chain_Reverse(Node* First) { if(First!=NULL) { Node * pre=NULL; Node * p=First; Node * q=First->next; while(q!=NULL) { p->next=pre; pre=p; p=q; q=q->next; } p->next=pre; return p; } return First; } int main() { printf("输入格式为:\nNum1\n+\nNum2\n"); while(1) { Node* Num1,* Num2; Num1=NULL; Num2=NULL; char tem; int fir=1; int fu1,fu2; int len1,len2; char Highest_Val1,Highest_Val2; len1=len2=0; while(scanf("%c",&tem))//第一个数 { if(tem=='\n') break; if(fir) { fir=0; if(tem=='-') { fu1=1; scanf("%c",&Highest_Val1); Num1=Node_Insert(Num1,Highest_Val1-'0'); ++len1; } else { fu1=0; ++len1; Highest_Val1=tem; Num1=Node_Insert(Num1,tem-'0'); } } else { ++len1; Num1=Node_Insert(Num1,tem-'0'); } } getchar(); getchar(); fir=1; while(scanf("%c",&tem))//第二个数 { if(tem=='\n') break; if(fir) { fir=0; if(tem=='-') { fu2=1; scanf("%c",&Highest_Val2); Num2=Node_Insert(Num2,Highest_Val2-'0'); ++len2; } else { fu2=0; ++len2; Highest_Val2=tem; Num2=Node_Insert(Num2,tem-'0'); } } else { ++len2; Num2=Node_Insert(Num2,tem-'0'); } } Node* result; jinwei=tuiwei=0; if(fu1==0&&fu2==0) //全正 { if(len1>len2) result=add1(Num1,Num2); else result=add1(Num2,Num1); result=Chain_Reverse(result); if(jinwei) printf("1"); order(result); printf("\n"); } else if(fu1==1&&fu2==1) //全负 { if(len1>len2) result=add1(Num1,Num2); else result=add1(Num2,Num1); result=Chain_Reverse(result); printf("-"); if(jinwei) printf("1"); order(result); printf("\n"); } else if((fu1==1&&fu2==0)||(fu1==0&&fu2==1)) //正负相加 { int bigger=1; int cmp=100; if(len1>len2) result=add2(Num1,Num2); else if(len1<len2) { bigger=2; result=add2(Num2,Num1); } else if(len1==len2) { Num1=Chain_Reverse(Num1); Num2=Chain_Reverse(Num2); cmp=My_Compare(Num1,Num2); Num1=Chain_Reverse(Num1); Num2=Chain_Reverse(Num2); if(cmp==1) result=add2(Num1,Num2); else if(cmp==-1) { bigger=2; result=add2(Num2,Num1); } } if(cmp==0) printf("0\n"); else { result=Chain_Reverse(result); Node* p=result; while(p->val==0) p=p->next; if(bigger==1) { if(fu1) printf("-"); } else if(bigger==2) { if(fu2) printf("-"); } while(p!=NULL) { printf("%d",p->val); p=p->next; } printf("\n"); } } } return 0; }
相关文章推荐
- 链表操作算法题合集
- C/C++面试之算法系列--典型的几个链表操作-逆序和重排
- 新手学习数据结构与算法---单链表的基本操作
- 算法与数据结构之十----内核中的链表操作学习
- 链表的特有算法操作
- Acm Club 1326:算法2-8~2-11:链表的基本操作
- 算法(05):基本链表的操作及双向链表
- 算法研究之——链表的一些操作(创建、打印,在头部、中间、尾部插入节点)
- 数据结构与算法-链表的基本操作---ShinPans
- 算法学习-数据结构之链表操作,创建,插入,删除,查找。
- 数据结构实验一--单链表的基本操作的算法
- 常用于面试的链表操作算法
- 韩顺平_PHP程序员玩转算法公开课(第一季)03_单链表crud操作之_水浒英雄排行算法_学习笔记_源代码图解_PPT文档整理
- 链表的相关操作算法
- JAVA中关于链表的操作和基本算法
- 单链表操作相关算法
- 算法之递归(3)- 链表操作
- HNCU1326:算法2-8~2-11:链表的基本操作
- 【数据结构与算法】java链表操作
- 常用链表操作算法