【C/C++数据结构实验】-实验3.链表基本操作的实现

引言

【C/C++数据结构实验】这个系列是我这个学期上的数据结构课上老师布置的实验,实验题目如下。我一般用c++,但是没有用到类啥的,就是普普通通的面向过程的思想不是面向对象的思想,只是借用c++的一些方便的环境,比如形参处可以写——*&,引用型参数很好用。

有需要的同学们自取吧,虽然算法不是很巧妙,但是都是我实实在在学完了自己一点点写出来的,运行结果是完全没问题的。正好这门课结课了,发上来我也能再复习一下!

一、实验题目

上机实验题3:链表基本操作的实现

建立单链表存储数据(10,20,30,40,50,60,70,80,90,100),要求:

(1)头插法或尾插法建立单链表,并输出单链表中所有元素;

(2)输出单链表中的最大值和最小值;

(3)键盘输入一个值x,输出链表中第一个值为x的元素的位序;

(4)键盘输入一位序值b,在第b个元素之前插入值为500的元素,输出链表中的所有数据;

(5)键盘输入位序值m,删除位序为m的元素,输出链表中的所有数据;

(6)输出单链表的长度。

(要求尽量将每一个操作模块化,可以将链表头指针设置成全局变量,也可以采用引用型参数。)

二、实验具体算法(c++)

#include<iostream>
#include<cstdlib>
#define MaxSize 50
using namespace std;
typedef int ElemType;
//声明LinkNode类型
typedef struct LNode{
	ElemType date;//存放元素值
    struct LNode *next;//指向后继节点的指针域
}LinkNode;
//建立单链表,头插法
void CreateListR(LinkNode *&L,ElemType a[],int n)
{int i=0;
L=(LinkNode*)malloc(sizeof(LinkNode));
L->next=NULL;//建立单链表并且为其初始化,将其next域置零
LinkNode *p;
while(i<=n)
{  
  p=(LinkNode*)malloc(sizeof(LinkNode));//为每一个a[i]对应的数值建立一个新的结点,将a[i]的数值赋给这个新的结点
  p->date=a[n-i];
  p->next=L->next;//将p所指的结点插入到L链表的头节点之后的首节点位置
  L->next=p;
  i++;
}
}
//比较大小
void MaxMin(LinkNode *L)
{int max,min;
max=L->next->date;
min=L->next->date;
LinkNode *p=L->next;//p指向L链表的首节点
while(p->next!=NULL)
    {
	if(max<p->date)
		max=p->date;
	if(min>p->date)
		min=p->date;
	    p=p->next;
	}
cout<<"max="<<max<<";min="<<min<<endl;
}
//输出链表
void DispList(LinkNode *&L)
{
	LinkNode *p=L->next;//p指向首结点
	while(p->next!=NULL)
	{
	cout<<p->date<<" ";
	p=p->next;//p指向L的下一个结点
	}
	cout<<endl;
}
//向链表中插入元素
bool ListInsert(LinkNode *&L,ElemType e,int i)
{int j=0;
	LinkNode *s,*p=L->next;
	if(i<1)
	{cout<<"插入位序不合理!"<<endl;//注意,插入函数内的if语句必须要保证:符合if语句条件,输出相应的信息后就结束,不再执行其后续语句,否则会顺序执行下面的语句。可以定义函数为bool型,在每个if语句后执行相应的return(可以在return前正常输出提示信息,而让return只起到符合语句就推出插入函数的作用)。但是一定不能采用break语句,否则还是会继续(也可能break不合理无法运行) 
	 return false;
	}
	while(p!=NULL&&j<i-1)//注意:链表无需注意该结点的下一个是否为空!!!!!只需要保证本结点不为空,就可以在本结点之前插入元素(链表存储空间不连续)
	{
		p=p->next;
		j++;
	}
	if(p==NULL)
	{
		cout<<"第"<<i-1<<"个结点为空结点,第"<<i<<"个结点超出链表范围,无法插入!"<<endl;
	     return false;
	}
	else
	{	s=(LinkNode*)malloc(sizeof(LinkNode));
	    s->date=e;
		s->next=p->next;
		p->next=s;
		cout<<"插入成功!"<<endl;
		return true;
	}
}
//删除链表某位序对应的元素
bool ListDelect(LinkNode *&L,int i)
{
	LinkNode *s,*p=L->next;//p指向L首结点
	if(i<1)
	{
	cout<<"位序错误!"<<endl;
	return false;
	}
	int j;
	for(j=1;p!=NULL&&j<i-1;j++)//初始p指向首节点,即链表中第一个元素,故初始j=1。j的数值对应链表中元素位序(逻辑位序)
		p=p->next;
	if(p==NULL)
	{
		cout<<"给出的位序超出链表元素最大位序,不存在该结点,无法删除!"<<endl;
		return false;
	}
	else
	{   
		s=p->next;//!!!此步非常关键,如果不把第i个指针存起来,在删除时,无论是先连接还是先free都会出现问题——丢失掉第i个结点后续的结点
		p->next = s->next;
		free(s);//释放掉第i个结点
	}
}
//按元素查找
void LocateList(LinkNode *L,ElemType e)
{
int i;
LinkNode *p=L->next;
for(i=1;p!=NULL&&p->date!=e;i++)//由于此处的p是指针,且没有为其分配内存空间,故p为纯指针,p表示指针p(所指向的值)的地址
   p=p->next;
if(p==NULL)
	cout<<"不存在数值"<<e<<",查找失败!"<<endl<<endl;
else
	cout<<"查找成功,该元素位序为:"<<i<<endl<<endl;//注意,一般将最后的成功的结果的条件放在最后面。“先排除所有错误的情况,剩下的就是正确的结果!!!”
}
//返回链表长度
int ListLength(LinkNode *&L)
{
	LinkNode *p=L->next;
	int i=1;
	while(p->next!=NULL)
	{
		p=p->next;
		i++;
	}
		return i;
}
//销毁链表
void DestroyList(LinkNode *&L)
{
	LinkNode *p=L,*s=L->next;
	while(s->next!=NULL)
	{
	   free(p);
	   p=s;
	   s=s->next;
	}
	free(s);
	cout<<endl<<"链表销毁成功!"<<endl<<endl;
}
int main()
{
	LinkNode *m;
	int x,b,k,a[MaxSize];
	for(int i=0;i<10;i++)
	a[i]=(i+1)*10;
	CreateListR(m,a,10);
	cout<<"(1)输出链表:"<<endl;
	DispList(m);
	cout<<endl<<"(2)链表中最大元素与最小元素:"<<endl;
	MaxMin(m);
	cout<<endl<<"(3)将查找链表中第一个值为x的元素的位序,请输入值x:";
	cin>>x;
	LocateList(m,x);
	cout<<"(4)将在位序b之前插入值为500的元素,请输入位序b:";
	cin>>b;
	ListInsert(m,500,b);
	cout<<"输出链表:"<<endl;
	DispList(m);
	cout<<endl<<"(5)将删除链表中位序为k的元素,请输入位序值k:";
	cin>>k;
	ListDelect(m,k);
	cout<<"输出链表:"<<endl;
	DispList(m);
	cout<<endl<<"(6)单链表长度为:"<<ListLength(m)<<endl;
	DestroyList(m);
}

三、实验总结与收获

我怕我忘了,我记性不好,所以当时把能想到的,还有我自己调出来的错误都给写在注释里了。说实话,当时写实验报告的时候,实验收获是最难写的,尤其是前几个实验没有总结的意识,导致写完程序过几天写报告的时候脑子空空如也。大家一定要想到什么就写出来,记在脑子里真的会忘的!!(也可能我是金鱼的记忆???)

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言实现: ```c #include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node* next; }; // 头插法建立单链表 struct Node* createListHead(int arr[], int n) { struct Node* head = NULL; for (int i = 0; i < n; i++) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = arr[i]; node->next = head; head = node; } return head; } // 尾插法建立单链表 struct Node* createListTail(int arr[], int n) { struct Node* head = NULL; struct Node* tail = NULL; for (int i = 0; i < n; i++) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = arr[i]; node->next = NULL; if (tail == NULL) { head = node; tail = node; } else { tail->next = node; tail = node; } } return head; } // 输出单链表中所有元素 void printList(struct Node* head) { while (head != NULL) { printf("%d ", head->data); head = head->next; } printf("\n"); } // 输出单链表中的最大值和最小值 void printMaxMin(struct Node* head) { int max = head->data; int min = head->data; while (head != NULL) { if (head->data > max) { max = head->data; } if (head->data < min) { min = head->data; } head = head->next; } printf("最大值:%d,最小值:%d\n", max, min); } // 输出链表中第一个值为x的元素的位序 void printXPos(struct Node* head, int x) { int pos = 1; while (head != NULL) { if (head->data == x) { printf("第一个值为%d的元素的位序:%d\n", x, pos); return; } head = head->next; pos++; } printf("链表中没有值为%d的元素\n", x); } // 在第b个元素之前插入值为500的元素,并输出链表中的所有数据 void insertBeforeB(struct Node* head, int b) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = 500; int pos = 1; while (head != NULL) { if (pos == b - 1) { node->next = head->next; head->next = node; break; } head = head->next; pos++; } printList(head); } // 删除位序为m的元素,并输出链表中的所有数据 void deletePosM(struct Node* head, int m) { if (m == 1) { head = head->next; printList(head); return; } int pos = 1; while (head != NULL) { if (pos == m - 1) { head->next = head->next->next; break; } head = head->next; pos++; } printList(head); } // 输出单链表的长度 int getLength(struct Node* head) { int length = 0; while (head != NULL) { length++; head = head->next; } return length; } int main() { int arr[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; int n = sizeof(arr) / sizeof(arr[0]); struct Node* head = createListHead(arr, n); printList(head); printMaxMin(head); printXPos(head, 30); insertBeforeB(head, 3); deletePosM(head, 5); printf("链表长度:%d\n", getLength(head)); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值