数据结构-单链表基本操作

实验二 线性链表

实验目的:

  1. 掌握线性表链式存储结构的定义方法;
  2. 掌握单链表、循环链表、双向链表各种基本操作的实现方法。

实验内容:

  1. 实现单链表类型,为其设计演示系统展示其基本操作。
    实现要求:
    1)单链表带头结点,元素为整型,基本操作包括:初始化、创建、遍历、读取第i个元素、插入、删除、求长度、清空、销毁;
    2)主程序用于验证各基本操作的正确性;
    3)主程序以用户和计算机对话的方式执行,实现过程为:
    • 在主程序中初始化单链表;
    • 主程序循环给出命令供用户选择,包括r(创建)、t(遍历)、g(读取第i个元素)、i(插入)、d(删除)、l(求长度)、c(清空)、 x(退出程序);
    • 当用户输入命令后,系统根据用户命令提示用户输入数据信息,主程序调用相应函数执行操作并反馈给用户相关信息;
    • 直至用户输入退出命令,销毁单链表。
    4)注意:基本操作间的约束关系,例如:单链表初始化后才可以执行创建操作;创建操作必须在单链表为空的前提下才可以执行,否则会导致内存泄露,因此再次执行创建操作前必须有清空操作。

  2. 约瑟夫环问题:编号为1,2,…,n的人顺时针围坐一圈,每人持一密码。一开始任取一正整数m作为报数上限,从第1个人开始报数,报至m的人出列,并以其密码作为新的m,他在顺时针方向的下一个人重新开始从1报数,如此下去,直至所有人出列。求出列顺序。
    实现要求:
    1) 根据实际问题需要合理设计存储结构;
    2) 程序实现过程为:
    • 用户输入人数n及报数上限初始值m;
    • 提示用户输入各人所持的密码;
    • 程序处理完毕输出结果。

第一题代码

#include<bits/stdc++.h>
#define size 100
using namespace std;

typedef struct lnode
{
	int data;
	struct lnode *next;	
}*link,lnode;

int check(char a)
{
	char s[size]="rtgidlc";
	int i;
	for(i=0;i<strlen(s);i++)
	{
		if(s[i]==a)
			return 1;
	}
	return 0;
}

void print()
{
	cout<<endl<<"r(创建)、t(遍历)、g(读取第i个元素)、i(插入)"<<endl;
	cout<<"d(删除)、l(求长度)、c(清空)、 x(退出程序)"<<endl;
}

void init(lnode *&l)			//初始化  
{
	l=(lnode *)malloc(sizeof(lnode));
	l->next=NULL;				//链表带头结点; 不带头节点:l=NULL 
}

void creat(lnode *&l)				//创建链表 
{
	int i,n,t; 
	init(l);
	lnode *p=l,*q;
	cout<<"输入链表元素的个数"<<endl;
	cin>>n;
	cout<<"输入元素:"; 
	for(i=0;i<n;i++)
	{
		q=(lnode *)malloc(sizeof(lnode));
		cin>>t;
		q->data=t;
		p->next=q;
		p=q;
	}
	p->next=NULL;
	cout<<"创建成功!"<<endl;
}

void trace(lnode *l)
{
	link p=l->next;
	if(p)
	{
		cout<<"元素为:";
		while(p)
		{
			cout<<p->data<<" ";
			p=p->next;
		}
		cout<<endl; 
	}
	else
		cout<<"链表为空"<<endl;
}

void getdata(lnode *l)
{
	int i,n;
	lnode *p=l->next;
	cout<<"输入查找的位置:"<<endl;
	cin>>n;
	for(i=0;i<n-1;i++) 
		p=p->next;
	if(p)
	{
		cout<<"元素为:"<<p->data<<endl; 
	}
	else
		cout<<"位置越界!"<<endl;
}

void insert(lnode *&l)
{
	int i,n,t;
	lnode *q=l,*r;
	cout<<"输入插入的位置:"<<endl;
	cin>>n; 
	cout<<"输入插入的元素:"<<endl;
	cin>>t;
	
	r=(lnode *)malloc(sizeof(lnode));
	r->data=t;
	r->next=NULL;
	
	for(i=0;i<n-1;i++) 
	{	
		q=q->next;
	}
	if(q)
	{
		r->next=q->next;
		q->next=r;
	}
	else
		cout<<"位置越界!"<<endl;
}

void del(lnode *&l)
{
	int i,n;
	lnode *p,*q=l;
	cout<<"输入要删除的位置:";
	cin>>n;
	
	for(i=0;i<n-1;i++) 
	{	
		q=q->next;
	}
	if(q)
	{
		p=q->next;
		q->next=q->next->next;
		free(p); 
		cout<<"删除成功!"<<endl;
	}
	else
		cout<<"位置越界!"<<endl; 
	
}

void getlength(lnode *l)			//获取链表长度 
{
	int llength=0;
	lnode *p=l->next;
	while(p)
	{
		llength++;
		p=p->next;
	}
	cout<<"长度为:"<<llength<<endl;
}

int main()
{
	char a;
	link l;
	cout<<"r(创建)、t(遍历)、g(读取第i个元素)、i(插入)"<<endl;
	cout<<"d(删除)、l(求长度)、c(清空)、 x(退出程序)"<<endl;
	while(cin>>a&&a!='x')
	{
		if(check(a))
		{
			switch(a)
			{
				case 'r':creat(l);	  print();break;
				case 't':trace(l);    print();break;
				case 'g':getdata(l);  print();break;
				case 'i':insert(l);   print();break;
				case 'd':del(l);      print();break;
				case 'l':getlength(l);print();break;
				case 'c':
				{
					init(l);     
					cout<<"清空成功!"<<endl; 
					print();break;
				} 
			}
		}
		else
			cout<<"请输入正确选项!"<<endl;
	}
}

运行结果:
创建单链表并遍历:
在这里插入图片描述

读取元素:
在这里插入图片描述

插入并遍历:
在这里插入图片描述

删除并遍历:
在这里插入图片描述

求表长+清空+遍历:
在这里插入图片描述

第二题代码:

#include<bits/stdc++.h>
#define size 100
using namespace std;

typedef struct lnode
{
	int data; 
	struct lnode *next;	
}*link,lnode;

void init(lnode *&l)			//初始化  
{
	l=(lnode *)malloc(sizeof(lnode));
	l->next=NULL;				//链表带头结点; 不带头节点:l=NULL 
}

void  creat(lnode *&l,int n)	//创建链表 
{
	int i,t; 
	init(l);
	lnode *p=l,*q;
	cout<<"请输入密码:";
	for(i=0;i<n;i++)
	{
		q=(lnode *)malloc(sizeof(lnode));
		cin>>t;
		q->data=t;
		q->next=NULL;
		p->next=q;
		p=q;
	}
	p->next=NULL;
}

void trace(lnode *l)			//遍历链表 
{
	link p=l->next;
	if(p)
	{
		cout<<"元素为:";
		while(p)
		{
			cout<<p->data<<" ";
			p=p->next;
		}
		cout<<endl; 
	}
	else
		cout<<"链表为空"<<endl;
}

int main()
{
	char a;
	link l;
	int n,m,i;
	cout<<"请输入n和m:";
	while(cin>>n>>m&&m>=1)
	{
		init(l);
 		creat(l,n);
 		trace(l);
 		lnode *p=l->next,*q=l,*r;
		while(n&&n!=1)
		{
			i=1;
			while(i!=m)
			{
				if(p&&p->next)
				{
					p=p->next;
					q=q->next;
				}
				else
				{
					p=l->next;
					q=l;
				}
				i++;
			}
			cout<<p->data<<" ";
			if(p->next)
			{
				q->next=p->next;
				r=p;
				p=p->next;
				free(r);
			}
			else
			{
				q->next=NULL;
				r=p;
				free(r);
				p=l->next;
				q=l;
			}
			n--;
		} 
 		cout<<p->data<<endl;
 		cout<<endl<<"请输入n和m:";
	}
	return 0;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。C语言中实现单链表基本操作包括:创建链表、插入节点、删除节点、查找节点、遍历链表等。其中,插入节点和删除节点是单链表的核心操作。在插入节点时,需要先找到要插入位置的前一个节点,然后将新节点插入到该节点之后;在删除节点时,需要先找到要删除节点的前一个节点,然后将该节点从链表中删除。以下是单链表基本操作代码示例: 1. 创建链表 ``` LinkList CreateList() { LinkList L = (LinkList)malloc(sizeof(LNode)); L->next = NULL; return L; } ``` 2. 插入节点 ``` bool ListInsert(LinkList L, int i, ElemType e) { if (i < 1) { return false; } LNode *p = L; int j = 0; while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL) { return false; } LNode *s = (LNode *)malloc(sizeof(LNode)); s->data = e; s->next = p->next; p->next = s; return true; } ``` 3. 删除节点 ``` bool ListDelete(LinkList L, int i, ElemType &e) { if (i < 1) { return false; } LNode *p = L; int j = 0; while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL || p->next == NULL) { return false; } LNode *q = p->next; e = q->data; p->next = q->next; free(q); return true; } ``` 4. 查找节点 ``` LNode *GetElem(LinkList L, int i) { if (i < 1) { return NULL; } LNode *p = L->next; int j = 1; while (p != NULL && j < i) { p = p->next; j++; } return p; } ``` 5. 遍历链表 ``` void TraverseList(LinkList L) { LNode *p = L->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值