数据结构实验1:线性表应用之单向链表

单向链表

目的要求
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;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值