#include<stdlib.h>
typedef struct node //結點類型(名稱)
{
int data; //結點的數據域
struct node *next; //結點的後繼指針
} linknode,*linkp;
/*單鏈表的使用~函數申明*/
linkp creatList(linkp head); //建立單鏈表
void printfList(linkp head); //打印鏈表
int lengthList(linkp head); //求單鏈表長度
int searchList(linkp head); //按序號查找表中元素
linkp insertLink(linkp head); //插入新結點
linkp deleteLink(linkp head); //刪除表中結點
linkp inversionLink(linkp head); //倒置鏈表
linkp mergeLink(linkp head,linkp head2);//合併鏈表
int main()
{
linkp head,head2,head3;
head=(linkp)malloc(sizeof(linknode)); //malloc分配內存成功返回的爲內存的首地址
head->next=NULL;
head=creatList(head); //建立單鏈表
head2=(linkp)malloc(sizeof(linknode));
head2->next=NULL;
head2=creatList(head2); //建立單鏈表
head3=(linkp)malloc(sizeof(linknode));
head3->next=NULL;
head3=mergeLink(head,head2);
printfList(head3); //單鏈表的順序合併
lengthList(head); //求鏈表長度
printfList(head); //打印鏈表
searchList(head); //按序號查找報表中元素
head=insertLink(head); //插入新結點
printfList(head);
head=deleteLink(head); //刪除表中結點
printfList(head);
head=inversionLink(head); //單鏈表的倒置
printfList(head);
}
//函數定義
/*單鏈表的基本操作*/
linkp creatList(linkp head) //建立單鏈表{
int a,i=1;
linkp p,t;
head=(linkp)malloc(sizeof(linknode));
t=head;
printf("請輸入第%d個數據元素:",i);
scanf("%d",&a); //輸入數據元素
while(a!=-1)
{
p=(linkp)malloc(sizeof(linknode)); //申請新結點
p->data=a;
t->next=p;
t=p; //存入數據,將新結點鏈入表尾
i++;
printf("請輸入第%d個數據元素:",i);
scanf("%d",&a);
}
t->next=NULL; //表尾後繼置空,防止野指針
return head;
}
void printfList(linkp head) //打印單鏈表
{
linkp p=head->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int lengthList(linkp head) //求單鏈表長度
{
linkp p=head->next;
int num=0;
while(p)
{
num++;
p=p->next;
}
printf("單鏈表長度爲 %d\n",num);
return num;
}
int searchList(linkp head) //按序號查找表中元素
{
int i,j=0;
linkp p=head;
printf("請輸入需要查找的元素編號:");
while(~scanf("%d",&i))
{
if(i<0)
printf("輸入有誤,請重新輸入:");
else break;
}
while(p->next&&j<i)
{
p=p->next;
j++;
}
if(j==i) printf("需要查找的元素值爲%d\n",p->data);
else printf("需要查找的元素不存在!!!");
}
linkp insertLink(linkp head) //插入新結點
{
int x,n,i=1;
linkp p,q;
printf("請輸入需要插入結點的位置:");
while (~scanf("%d",&x))
{
if(x<1||x>lengthList(head)+1)
printf("輸入有誤,請重新輸入:");
else
{
printf("請輸入要插入的數據元素:");
scanf("%d",&n);
break;
}
}
p=head;
while(i!=x)
{
p=p->next;
i++;
}
q=(linkp)malloc(sizeof(linknode));
q->data=n;
q->next=p->next;
p->next=q;
return head;
}
linkp deleteLink(linkp head) //刪除單鏈表結點
{
int n,i=1;
linkp p,q;
p=head;
printf("請輸入需要刪除結點的位置:");
while(~scanf("%d",&n))
{
if(n<1||n>lengthList(head))
{
printf("輸入有誤,請重新輸入:");
}
else break;
}
while(i!=n)
{
p=p->next;
i++;
}
q=p->next;
p->next=q->next;
return head;
}
/*單鏈表的擴展運算*/
linkp inversionLink(linkp head) //倒置單鏈表
{
linkp p,q;
p=head->next;
head->next=NULL;
while(p)
{
q=p;
p=p->next; //q=p,對指針q進行操作同時也會影響到指針p
q->next=head->next;
head->next=q;
}
return head;
}
linkp mergeLink(linkp head,linkp head2) //單鏈表的順序合併
{
linkp p1,p2,head3;
if(head->next->data < head2->next->data) //找出兩個鏈表中第一個結點較小的結點,head3記錄較小結點的頭結點
{
head3=head;
p1=head->next;
p2=head2->next;
}
else
{
head3=head2;
p2=head2->next;
p1=head->next;
}
linkp r=head3;
while(p1&&p2) //在兩個鏈表中遍歷比較,將值較小的結點鏈接到r結點後
{
if(p1->data <= p2->data)
{
r->next=p1;
r=p1;
p1=p1->next;
}
else
{
r->next=p2;
r=p2;
p2=p2->next;
}
} //將p1或p2剩餘的結點鏈到r之後,完成整個合併的過程
if(p1)
r->next=p1;
if(p2)
r->next=p2;
return head3;
}