单链表的基本操作
背景知识:单链表的插入、删除及应用。 目的要求: 1.掌握单链表的存储特点及其实现。 2.掌握单链表的插入、删除算法及其应用算法的程序实现。 实验内容: 编写一个完整的程序,实现单链表的生成、插入、删除、输出等基本操作。 (1) 随机产生或键盘输入一组元素,建立一个带头结点的单向链表(无序)。 (2) 计算单链表的长度,遍历单链表。 (3) 把单链表中的元素逆置(不允许申请新的结点空间)。 (4) 在单链表中删除所有值为偶数的元素结点。 (5) *编写在非递减有序单链表中插入一个元素使链表元素仍有序的函数,并利用该函数 建立一个非递减有序单链表。 (6) * 利用算法 5 建立两个非递减有序单链表,然后合并成一个非递增有序链表。 (7) * 利用算法 5 建立两个非递减有序单链表,然后合并成一个非递减有序链表。 (8) * 利用算法 1 建立的链表,实现将其分解成两个链表,其中一个全部为奇数,另一个 全部为偶数(尽量利用已知的存储空间)。 (9) * 采用单链表实现一元多项式的存储并实现两个多项式相加并输出结果。 (10) 在主函数中设计一个简单的菜单,分别调试上述算法。
代码如下:
DS.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status
;
LinkList.h
#include "DS.h"
typedef int Elemtype
;
typedef struct Node
{
Elemtype data
;
struct Node
*next
;
}Lnode
,*LinkList
;
void menu();
Status
Init_Linklist(LinkList
&L
);
Status
Creat_Linklist(LinkList
&L
);
void Disp_Linklist(LinkList L
);
int length_Linklist(LinkList L
);
void Reverse_Linklist(LinkList L
);
void DelEven_Linklist(LinkList L
);
Status
Insert_Linklist(LinkList L
, int x
);
Status
CreatOrder_Linklist(LinkList
&L
);
void MergeDescend_Linklist(LinkList La
, LinkList Lb
, LinkList
&Lc
);
void MergeAscend_Linklist(LinkList La
, LinkList Lb
, LinkList
&Lc
);
void Split_Linklist(LinkList La
, LinkList
&Lb
);
LinkList.cpp
#include "LinkList.h"
void menu(void)
{
printf("\t\t\t 单链表基本操作\n\n");
printf("\t\t\t1.建 立 单 链 表\n");
printf("\t\t\t2.遍 历 单 链 表\n");
printf("\t\t\t3.计 算 链 表 长 度\n");
printf("\t\t\t4.链 表 逆 置\n");
printf("\t\t\t5.删 除 偶 数 节 点\n");
printf("\t\t\t6.生 成 值 有 序 单 链 表\n");
printf("\t\t\t7.合 并 生 成 降 序 链 表\n");
printf("\t\t\t8.合 并 生 成 升 序 链 表\n");
printf("\t\t\t9.分 解 链 表\n");
printf("\t\t\t0.退 出\n\n");
}
Status
Init_Linklist(LinkList
&L
)
{
L
=(LinkList
)malloc(sizeof(Lnode
));
if(!L
) return ERROR
;
L
->next
=NULL;
return OK
;
}
Status
Creat_Linklist(LinkList
&L
)
{
int x
;
LinkList p
,rear
;
if (Init_Linklist(L
)== ERROR
)
return ERROR
;
rear
= L
;
printf("输入-1表示输入结束\n");
while(scanf("%d",&x
),x
!= -1)
{
p
= (LinkList
)malloc(sizeof(Lnode
));
if(!p
) return ERROR
;
p
->data
= x
;
rear
->next
= p
;
rear
= p
;
}
rear
->next
= NULL;
return OK
;
}
void Disp_Linklist(LinkList L
)
{
LinkList p
;
p
= L
->next
;
while(p
)
{
printf("%d ", p
->data
);
p
= p
->next
;
}
printf("\n");
}
int length_Linklist(LinkList L
)
{
int count
= 0;
LinkList p
;
p
= L
->next
;
while (p
)
{
count
++;
p
= p
->next
;
}
return count
;
}
void Reverse_Linklist(LinkList L
)
{
LinkList p
, q
;
p
= L
->next
;
L
->next
= NULL;
while(p
)
{
q
= p
->next
;
p
->next
= L
->next
;
L
->next
= p
;
p
= q
;
}
}
void DelEven_Linklist(LinkList L
)
{
LinkList p
, q
;
q
= L
;
p
= L
->next
;
while (p
)
{
if (p
->data
% 2 == 0)
{
q
->next
= p
->next
;
delete(p
);
p
= q
->next
;
}
else
{
q
= p
;
p
= p
->next
;
}
}
}
Status
Insert_Linklist(LinkList L
, int x
)
{
LinkList p
, q
, px
;
px
= (LinkList
)malloc(sizeof(Lnode
));
if(!px
) return ERROR
;
px
->data
= x
;
q
= L
;
p
= L
->next
;
while (p
)
{
if (x
> p
->data
)
{
q
= p
;
p
= p
->next
;
}
else
{
px
->next
= p
;
q
->next
= px
;
return OK
;
}
}
px
->next
= p
;
q
->next
= px
;
return OK
;
}
Status
CreatOrder_Linklist(LinkList
&L
)
{
LinkList p
;
int x
;
if (Init_Linklist(L
)== ERROR
)
return ERROR
;
printf("输入新链表的节点值,输入-1表示输入结束\n");
while(scanf("%d",&x
),x
!= -1)
{
if (Insert_Linklist(L
,x
)==ERROR
)
return ERROR
;
}
return OK
;
}
void MergeDescend_Linklist(LinkList La
, LinkList Lb
, LinkList
&Lc
)
{
LinkList pa
, pb
, pc
,q
;
pa
= La
->next
;
pb
= Lb
->next
;
pc
= Lc
= La
;
Lc
->next
= NULL;
while(pa
|| pb
)
{
if (!pa
)
{
q
=pb
;
pb
=pb
->next
;
}
else if (!pb
)
{
q
=pa
;
pa
=pa
->next
;
}
else if (pa
->data
<= pb
->data
)
{
q
=pa
;
pa
= pa
->next
;
}
else
{
q
=pb
;
pb
= pb
->next
;
}
q
->next
= Lc
->next
; Lc
->next
= q
;
}
delete Lb
;
}
void MergeAscend_Linklist(LinkList La
, LinkList Lb
, LinkList
&Lc
)
{
LinkList pa
, pb
, pc
;
pa
= La
->next
;
pb
= Lb
->next
;
pc
= Lc
= La
;
while(pa
&& pb
)
{
if(pa
->data
<= pb
->data
)
{
pc
->next
= pa
; pc
= pa
; pa
= pa
->next
;
}
else
{
pc
->next
= pb
; pc
= pb
; pb
= pb
->next
;
}
}
pc
->next
= pa
? pa
: pb
;
free(Lb
);
}
void Split_Linklist(LinkList La
, LinkList
&Lb
)
{
LinkList p
,q
;
Lb
= (LinkList
)malloc(sizeof(Lnode
));
Lb
->next
= NULL;
q
= La
;
p
= La
->next
;
while (p
)
{
if (p
->data
% 2 ==1)
{
p
= p
->next
;
q
= q
->next
;
}
else
{
q
->next
= p
->next
;
p
->next
= Lb
->next
;
Lb
->next
= p
;
p
= q
->next
;
}
}
}
main.cpp
#include "LinkList.h"
int main()
{
int choice
, length
;
LinkList L
, La
, Lb
, Lc
;
while(1)
{
menu();
printf("选择你的操作:");
scanf("%d",&choice
);
switch(choice
)
{
case 1:
if(Creat_Linklist(L
))
printf("单链表创建成功\n");
else
printf("单链表创建失败\n");
break;
case 2:
Disp_Linklist(L
);
break;
case 3:
length
= length_Linklist(L
);
printf("单链表长度为:%d\n",length
);
break;
case 4:
Reverse_Linklist(L
);
printf("逆置后的链表为:\n");
Disp_Linklist(L
);
break;
case 5:
DelEven_Linklist(L
);
printf("新链表为:\n");
Disp_Linklist(L
);
break;
case 6:
if(CreatOrder_Linklist(L
))
{
printf("值有序链表为:\n");
Disp_Linklist(L
);
}
else
printf("单链表创建失败\n");
break;
case 7:
CreatOrder_Linklist(La
);
CreatOrder_Linklist(Lb
);
MergeDescend_Linklist(La
, Lb
, Lc
);
printf("合并后的新链表为:\n");Disp_Linklist(Lc
);
break;
case 8:
CreatOrder_Linklist(La
);
CreatOrder_Linklist(Lb
);
MergeAscend_Linklist(La
, Lb
, Lc
);
printf("合并后的新链表为:\n");Disp_Linklist(Lc
);
break;
case 9:
Creat_Linklist(L
);
Split_Linklist(L
, Lb
);
printf("分裂后的新链表为:\n");
Disp_Linklist(L
);
Disp_Linklist(Lb
);
break;
case 0:
return 0;
default:
printf("输入错误,请重新输入\n");
}
} }
运行结果: