单向链表
目的要求
1.掌握单链表的存储特点及其实现。
2.掌握单链表的插入与删除算法的程序实现。
实验内容
1.随机产生或键盘输入一组元素(不少于 10 个元素),建立一个带头结点的单链表。
2.把单链表中的元素逆置(不允许申请新的结点空间)。
3.删除单链表中所有的偶数元素结点。
4.编写在非递减有序链表中插入一个元素使链表元素仍有序的函数,利用该函数建立一个
非递减有序单链表。
5.利用算法 4 建立两个非递减有序单链表,然后合并成一个非递增链表。
6.把算法 1 建立的链表分解成两个链表,其中一个全部为奇数,另一个全部为偶数(尽量
利用已有存储空间)。
7.在主函数中设计一个简单菜单,调用上述算法。
实验说明
1.结点类型定义
typedef int ElemType; // 元素类型
typedef struct LNode
8 / 14
{
ElemType data ;
struct LNode * next ;
} LNode, *pLinkList ;
2.为了简单,采用带头结点的单链表。
源代码
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int ElemType; //元素类型
typedef struct LNode
{
ElemType data;
struct LNode * next;
}LNode,*pLinkList;
typedef LNode * PNode;
//创建带有头结点的空链表
pLinkList SetNullList_Link()
{
pLinkList head = (pLinkList)malloc(sizeof(LNode)); //申请头结点空间
if (head != NULL)
head->next = NULL;
else
printf("申请头节点空间失败!\n");
return head; //返回头指针
}
int IsNull_Link(pLinkList head) //判断链表是否为空,空返回1,非空返回0
{
return(head->next == NULL);
}
//随机生成元素建立单链表
void CreateList(pLinkList head, int m)
{
PNode p = NULL;
PNode temp = NULL;
temp = head;
srand(unsigned(time(NULL))); //设置随机数种子
for (int i = 0;i < m;i++)
{
p = (PNode)malloc(sizeof(LNode));
p->data = rand() % 100 + 1;
temp->next = p;
temp = p;
}
temp->next = NULL;
}
//打印单链表
void printList(pLinkList list)
{
PNode temp = list->next;
//if (!temp)
// printf("链表为空!\n");
int i = 0;
while (temp)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
//销毁链表,释放空间
void DelList_Link(pLinkList head)
{
pLinkList p = NULL;
while (head->next)
{
p = head->next;
head->next = p->next;
free(p);
}
free(head);
head = NULL;
}
//单链表逆置
int Reserve_List(pLinkList head)
{
PNode temp;
if (head->next == NULL)
{
printf("The List is NULL!\n");
return 0;
}
PNode privious = head->next;
PNode current = privious->next;
privious->next = NULL;
if (current == NULL || privious == NULL)
return 0;
while (current)
{
temp = current->next;
current->next = privious;
privious = current;
current = temp;
}
head->next = privious;
return 1;
}
//删除单链表中所有的偶数元素结点
int Delete_oushu(pLinkList head)
{
if (head->next == NULL)
{
printf("The List is NULL!\n");
return 0;
}
PNode p = head->next;
PNode beforeP = head;
PNode temp;
while (p)
{
if (p->data % 2 == 0) {
temp = p;
p = p->next;
free(temp);
beforeP->next = p;
}
else {
beforeP = p;
p = p->next;
}
}
return 1;
}
//非递减顺序排序
int Sort_LinkList(pLinkList head)
{
PNode p, q;
PNode min = NULL;
ElemType temp;
if (head->next == NULL) {
printf("The List is NULL!!\n");
return 0;
}
for (p = head->next; p->next; p = p->next)
{
min = p;
for (q = p->next; q; q = q->next)
{
if (q->data < min->data)
min = q;
}
temp = p->data;
p->data = min->data;
min->data = temp;
}
return 1;
}
//插入一个元素后链表元素仍有序
int Insert_sort(pLinkList list, ElemType x)
{
PNode p = list;
while (p->next && x>p->next->data)
p = p->next;
PNode q = (PNode)malloc(sizeof(LNode));
if (q == NULL)
return 0;
else
{
q->data = x;
q->next = p->next;
p->next = q;
return 1;
}
}
//将两个链表合并成一个非递增链表
int Combine_List(pLinkList list1, pLinkList list2)
{
if (list1->next == NULL) {
printf("The List1 is NULL!!\n");
return 0;
}
PNode p1 = list1->next;
PNode p2 = list2->next;
while (p1->next)
p1 = p1->next;
p1->next = p2;
Sort_LinkList(list1);
Reserve_List(list1);
return 1;
}
//将链表分解成两个链表,其中一个全部为奇数,另一个全部为偶数
void Devide_Link(pLinkList list1, pLinkList list2)
{
PNode p = list1->next;
PNode beforeP = list1;
while (p)
{
if (p->data % 2 == 0) {
list2->next = p;
list2 = p;
p = p->next;
beforeP->next = p;
}
else {
beforeP = p;
p = p->next;
}
}
list2->next = NULL;
}
int main()
{
int Index;
pLinkList list1 = NULL;
list1 = SetNullList_Link();
printf(" 单链表\n");
printf(" ************************************************************************\n");
printf(" 1.随机产生一组元素(不少于10个元素),建立一个带头结点的单链表\n");
printf(" 2.把单链表中的元素逆置(不允许申请新的结点空间)\n");
printf(" 3.删除单链表中所有的偶数元素结点\n");
printf(" 4. 非递减顺序排序\n");
printf(" 5. 在非递减有序链表中插入一个元素使链表元素仍有序\n");
printf(" 6. 利用算法5建立两个非递减有序单链表,然后合并成一个非递增链表\n");
printf(" 7. 将链表分解成两个链表,其中一个全部为奇数,另一个全部为偶数\n");
printf(" 0. 退出并删除链表\n");
printf(" ************************************************************************\n");
while (true)
{
printf("\n请输入一个序号:");
scanf("%d", &Index);
switch (Index)
{
case 0:
{
DelList_Link(list1); //删除链表,释放空间
return 0;
}
case 1:
{
int num;
printf("输入要随机产生的元素的个数(不少于10个):");
scanf("%d", &num);
CreateList(list1, num);
printf("\n生成list1成功: ");
printList(list1);
}break;
case 2:
{
if (Reserve_List(list1)) {
printf("\n链表list1元素逆置: ");
printList(list1);
}
}break;
case 3:
{
if(Delete_oushu(list1))
{
printf("\n成功删除list1偶数元素的结点: ");
printList(list1);
}
}break;
case 4:
{
if(Sort_LinkList(list1))
{
printf("\n非递减排序list1: ");
printList(list1);
}
}break;
case 5:
{
ElemType x;
printf("\n请输入要插入list1的元素:");
scanf("%d", &x);
if (Insert_sort(list1, x))
{
printf("\n插入成功: ");
printList(list1);
}
}break;
case 6:
{
int num1;
pLinkList list2 = NULL;
list2 = SetNullList_Link();
printf("\n请输入要插入list2的元素个数: ");
scanf("%d", &num1);
ElemType *m;
m = (ElemType *)malloc(sizeof(ElemType)*num1);
printf("\n请输入这%d个元素:", num1);
for (int i = 0;i < num1;i++)
scanf("%d", &m[i]);
for (int i = 0;i < num1;i++)
Insert_sort(list2, m[i]);
printf("\n插入成功list2: ");
printList(list2);
if (Combine_List(list1, list2))
{
printf("\n合并list1和list2后(降序): ");
printList(list1);
}
}break;
case 7:
{
pLinkList list3 = NULL;
list3 = SetNullList_Link();
Devide_Link(list1, list3);
printf("奇数链表: ");
printList(list1);
printf("偶数链表: ");
printList(list3);
DelList_Link(list3); //释放链表
}break;
default:
printf("输入有误,请输入数字0-7!\n");
break;
}
}
system("pause");
return 0;
}