您的位置:首页 > 其它

链表操作算法题合集

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: