感覺筆試的時候考單鏈表也挺多的,寫一些基礎的練練手,沒有經過大量的測試,如果發現邊界錯誤請留言
#include <iostream>
#include <cstdio>
#include <cstring>
#include <malloc.h>
using namespace std;
typedef int type;
typedef struct Node
{
type data;
struct Node *next;
}Node,*List;
//創建鏈表,輸入0或者'\0'結尾
void create(List &head)
{
int temp;
Node *p;
p=head;
while(cin>>temp)
{
if(temp==0)
return;
Node *q=(List)malloc(sizeof(Node));
q->data=temp;
q->next=NULL;
p->next=q;
p=q;
}
// head=head->next;
}
//打印鏈表
void print(List head)
{
printf("當前鏈表爲:\n");
while(head)
{
printf("%d ",head->data);
head=head->next;
}
printf("\n");
}
//獲取鏈表的長度
int get_len(List head)
{
int num=0;
while(head)
{
num++;
head=head->next;
}
return num;
}
//刪除值爲t的節點
void del(List &head,type t)
{
List pre=head,cur=head;
if(cur->data==t)
{
head=head->next;
free(pre);
return ;
}
cur=cur->next;
while(cur)
{
if(cur->data==t)
{
if(cur->next==NULL)
{
free(cur);
return;
}
else
{
pre->next=cur->next;
free(cur);
return;
}
}
pre=pre->next;
cur=cur->next;
}
printf("cannot find %d!\n",t);
}
//在某位置上插入一個節點
void ins(List &head,int pos,type t)
{
Node *node=(List)malloc(sizeof(Node));
node->data=t;
node->next=NULL;
if(pos==0)
{
node->next=head;
head=node;
return ;
}
int num=1;
List pre=head,cur=head;
cur=cur->next;
while(cur)
{
if(pos==num)
{
node->next=cur;
pre->next=node;
return;
}
num++;
pre=pre->next;
cur=cur->next;
}
printf("position %d error!\n",pos);
}
//用冒泡實現的鏈表排序
void Sort(List &head)
{
if(head==NULL)
return;
for(List cur=head,nxt=head->next;nxt;cur=cur->next,nxt=nxt->next)
{
for(List cur=head,nxt=head->next;nxt;cur=cur->next,nxt=nxt->next)
{
if(cur->data>nxt->data)
{
type temp=cur->data;
cur->data=nxt->data;
nxt->data=temp;
}
}
}
}
//鏈表逆置
List Reverse(List head)
{
if(head==NULL||head->next==NULL)
{
return head;
}
List p1,p2,p3;
p1=head;
p2=head->next;
while(p2)
{
p3=p2->next;
p2->next=p1;
p1=p2;
p2=p3;
}
head->next=NULL;
return p1;
}
//合併兩個鏈表,並且不佔用多餘內存,且實現去重複的效果
List merge(List a,List b)
{
if(a==NULL)
return b;
else if(b==NULL)
return a;
List chead=(List)malloc(sizeof(Node));
List c=chead;
while(a&&b) //思想就是將兩個鏈表串起來
{
if(a->data<b->data)
{
c->next=a;
c=c->next;
a=a->next;
}
else if(a->data>b->data)
{
c->next=b;
c=c->next;
b=b->next;
}
else
{
c->next=a; //精髓,如果此時將c移動,當a是2,2,2,b是2,2,2的時候,不是隻出了一個2
//而這麼寫證明下面的值肯定比當前的大,然後c自然會移動
b=b->next;
}
}
c->next=a?a:b;
return chead->next;
}
int main()
{
printf("輸入鏈表,以0結尾\n");
List l=(List)malloc(sizeof(Node));
create(l);
l=l->next;
print(l);
printf("鏈表長度爲:%d\n",get_len(l));
type t;
printf("輸入要刪除的值:");
scanf("%d",&t);
del(l,t);
print(l);
type pos;
printf("輸入插入的位置和值:");
scanf("%d%d",&pos,&t);
ins(l,pos,t);
print(l);
Sort(l);
printf("------排序後的鏈表-------\n");
print(l);
printf("-輸入要合併的新鏈表,以0結尾\n");
List ll=(List)malloc(sizeof(Node));
create(ll);
ll=ll->next;
Sort(ll);
printf("--------合併之後--------\n");
l=merge(l,ll);
print(l);
l=Reverse(l);
printf("------鏈表逆置後-------\n");
print(l);
free(l);
return 0;
}