实验1.2 链表的操作

实验1.2 链表的操作

头文件

#include<conio.h>
#include<dos.h>
#include<stdio.h>
#include<stdlib.h>

结构体定义

#define LEN sizeof(LNode) //定义LEN为一个结点的长度

typedef enum
{
	False = 0,
    True = 1,
} BOOL;  //定义BOOL型
typedef struct node
{
	char date; //数据域
	struct node* next; //嵌套定义 指向下一个结点的指针
}LNode,*LinkList;

函数声明

void CreatList(LinkList&, int);
BOOL ListInsert(LinkList&, int,char);
BOOL ListDelete(LinkList&,int,char &);
BOOL ListFind_keyword(LinkList,char ,int &);
BOOL ListFind_order(LinkList, char &, int);
void ListPrint(LinkList);

主函数

int main()
{
	LinkList L;
	BOOL temp;
	int num, loc=0, flag = 1,j;
	char  ch,h;
	printf("本程序实现链式结构的线性表操作。\n");
	printf("可进行插入,删除,定位,查找等操作。\n");
	printf("请输入初始时链表的长度:"); //输入生成单链表时的元素个数
	scanf("%d", &num);
	CreatList(L, num); //生成单链表
	ListPrint(L);
	while (flag)
	{
		printf("\n请选择需要进行的操作\n");
		printf("1.显示所有元素\n");
		printf("2.插入一个元素\n");
		printf("3.删除一个元素\n");
		printf("4.按关键字查找元素\n");
		printf("5.按序号查找元素\n");
		printf("6.退出程序\n");
		scanf("%d", &j);
		switch (j)
		{
		case 1:ListPrint(L);break;
		case 2: 
		    {printf("请输入要插入的位置:\n");
			scanf("%d",  &loc);
			scanf("%c", &h); //如果不加这行吸收回车键,则输入位置后的回车会被存入ch中,导致结果错误
			printf("请输入元素(一个字符)\n");
			scanf("%c", &ch);
			temp = ListInsert(L, loc, ch); //执行插入元素的操作
			if (temp == False)
				printf("插入失败\n");
			else
				printf("插入成功\n");
			ListPrint(L);}
			    break;
		case 3: {printf("请输入要删除的元素所在位置");
			scanf("%d", &loc);
			temp = ListDelete(L, loc, ch); //执行删除元素的操作
			if (temp == False)
				printf("删除失败!\n");
			else
				printf("成功删除了值为%c的元素", ch);
			ListPrint(L);}
				break;
		case 4: {if (L->next == NULL)
			    printf("链表为空\n");
			else
		    {
		        printf("请输入要查找的元素(一个字符):");
				scanf("%c%c", &h, &ch); //输入j后的回车会被存入ch,故需要一个额外的h来吸收掉回车
				temp = ListFind_keyword(L, ch, loc); //执行按关键字查找元素的操作
				if (temp == False)
					printf("没有找到该元素!\n");
				else
					printf("该元素在链表的第%d个位置。\n", loc);
	        }}	
				break;
		case 5: {if (L->next == NULL)
			    printf("链表为空!\n");
		    else
		    {
			    printf("请输入要查找的位置:");
				scanf("%d", &loc);
				temp = ListFind_order(L, ch,  loc); //执行按序号查找元素的操作
				if (temp == False)
					printf("该位置不存在!\n");
				else
					printf("第%d个元素是:%c\n", loc, ch);
		    }}
				break;
		default: {flag = 0;printf("程序结束,按任意键退出!\n");}
			   break;
		}
	}
}

生成一个带头结点的有n个元素的单链表

void CreatList(LinkList& v, int n)
{
	int i;
	LinkList p;
	v = (LinkList)malloc(LEN); //生成头结点
	v->next = NULL;
	printf("请输入%d个字符,例如:abcdefg\n", n);
	for (i = n;i >0 ;i--) //采用头插法,故而现输入反而在后面结点
	{
		p = (LinkList)malloc(LEN); //生成新结点
		scanf(" %c", &p->date);
		p->next = v->next; //勾链从右往左进行
		v->next = p;
	}
	char h;//因为输入之后的回车键会影响之后的输入故而在此消耗掉回车
	scanf_s("%c", &h);

}

在单链表的第i个位置插入e

BOOL ListInsert(LinkList& v, int i, char e)
{
	LinkList p, s;
	int j = 0;
	p = v;
	while (p && j < i - 1) //当p结点不为空且插入位置在表内时进行循环
	{
		p = p->next; //p结点依次后移。同时j作为位置计数也不断后移
		++j; //结束时p指向第i-1个位置
	}
	if (!p || j > i - 1)
		return False; //没有找到该位置
	s = (LinkList)malloc(LEN); //生成新结点
	s->date = e;
	s->next = p->next; //将新结点插入到单链表中,即修改指针,完成插入操作
	p->next = s;
	return True;
}

在单链表中删除第i个元素

BOOL ListDelete(LinkList& v, int i, char& e)
{
	LinkList p, q;
	int j = 0;
	p = v;
	while (p->next && j < i - 1)
	{
		p = p->next;
		++j; //结束时p指向第i-1个位置
	}
	if (!(p->next) || j > i - 1)
		return False;
	q = p->next; //此处小心p q输入错误
	p->next = q->next;
	e = q->date; //e取得该元素的值,即修改指针删除结点p
	free(q);
	return True;
}

在单链表中查找关键字为e的元素

BOOL ListFind_keyword(LinkList v, char e, int &i)
{
	i = 1;
	LinkList p;
	p = v->next;
	while ((p->date != e) && (p->next != NULL)) 
	{
		p = p->next;
		i++; //循环结束后i的值就是值为e的结点的位置
	}
	if (p->date != e)
		return False;
	else
		return True;
}

在单链表中查找第i个元素

BOOL ListFind_order(LinkList v, char& e, int i)
{
	LinkList p;
	int j = 0;
	p = v;
	while (p->next && j < i)
	{
		p = p->next;
		++j; //循环结束时j==i
	}
	if (j != i)
		return False;
	e = p->date;
	return True;
}

显示链表所有元素

void ListPrint(LinkList v)
{
	LinkList q;
	q = v->next;
	printf("链表所有元素:");
	while (q != NULL)
	{
		printf("%c ", q->date);
		q = q->next;
	}
	printf("\n");
}

运行结果

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值