用C语言描述数据结构_线性表_顺序表

版权声明:如需转载,请注明出处 https://blog.csdn.net/qq_36260974/article/details/84175150

顺序表的概念和运算

- 什么是线性表
线性表是由n个元素(结点)组成的有限序列。n为线性表的长度,n=0时称为空表。

- 线性表的逻辑特征
(1)对于非空的线性表,有且有一个开始结点,它没有直接前驱,而仅有一个直接后继。
(2)对于非空的线性表,有且有一个终端结点,它没有直接后继,而仅有一个直接前驱。
(3)对于非空的线性表,内部结点(除去开始结点和终端结点)都有且仅有一个直接前驱和一个直接后继。

- 图示
在这里插入图片描述
- 什么是顺序表
把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里,这种方法存储的线性表简称为顺序表。例如一维数组就是采用顺序存储表示的。

- 顺序表的描述

typedef int datatype;//该用法有疑惑请看脚注
#define M 100
typedef struct 
{ 
	datatype data[M];
	int last;
}sequenlist; 
sequenlist  L;

我们将与顺序表有关的信息封装在一起,而将顺序表类型sequenlist定义为一个结构体,这样定义使得对某一顺序表L(L是sequenlist类型的指针变量)的引用仅涉及结构变量*L,它符合程序设计的思想。

- 顺序表上的基本运算
在这里插入图片描述
数据的插入:对于顺序表上的数据插入,除了在表的末尾插入之外,在其他地方插入需要移动插入结点及其后的所有结点,该步骤完成以后才能进行数据插入操作,同时表的长度(last)也需要随之发生改变(增加),如下图所示:
在这里插入图片描述

代码实现:

//移动元素位置(i为数据x将要插入的位置)
for (int j = L.last; j >= i - 1; j--)
{
	L.data[j + 1] = L.data[j];
}
//插入数据(x为插入数据)
L.data[i - 1] = x;
//表的最后一个元素的指向增加(当前表中实际存放元素数量)
L.last++;

数据的删除:对于顺序表上数据的删除,其思想与插入相反。首先选定需要删除的数据(位置),然后,移动删除数据之后的元素,均向前移动一位。事实上,删除数据,并不是真正意义上的删除,而只是数据覆盖而已,表现上为数据的删除,同时表的长度(last)也需要随之发生改变(减小),如下图所示:
在这里插入图片描述
代码实现:

//移动元素位置(i为删除数据的位置)
for (j = i; j <= L.last; j++)
{
	L.data[j - 1] = L.data[j];
}
//表的最后一个元素的指向减小(当前表中实际存放元素数量)
L.last--;

表的长度:顺序表使用一维数组来存储,其长度为该数组实际存储数据元素个数。即为last指向的数组下标值(也是last的值),所以表的长度为last。

表的置空:顺序表的置空,是直接将last指向的值赋值为-1,当新的数据进入,又会从数组0索引处开始覆盖之前的数据,由于存在last指向,之前的数据不会对后续表中数据产生影响;而不应使用移除数据的方法实现表的置空。

至此,顺序表上的关键操作(插入、删除)叙述完毕。

程序运行结果图:
在这里插入图片描述
在这里插入图片描述
以下为完整代码:

#include"stdio.h" 
#include"stdlib.h" 
typedef int datatype;//该用法有疑惑请看脚注
#define M 100
#define N 10
typedef struct
{
	datatype data[M];
	int last;
}sequenlist;
sequenlist  L;//静态
/*
sequenlist * Create_sequenlist()
{
sequenlist *p;
p= (sequenlist*)malloc(sizeof(sequenlist));
p->last = -1;
return p;
}//动态
*/
void shuru()
{
	for (int i = 0; i<N; i++)
	{
		L.data[i] = rand() % 101;
		L.last = i;
	}
	printf("\n\t\t数据已产生!\n");
}

void shuchu()
{
	int i;
	if (L.last != -1)
	{
		printf("\n\t\t顺序表中的内容为\n\t");
		for (i = 0; i <= L.last; i++)//
		{
			printf("\t%d", L.data[i]);
		}
	}
	else
	{
		printf("\n\t\t顺序表为空!\n");
	}
}

void zhikong()
{
	L.last = -1;
	printf("\n\t\t已清空!\n");
}

void changdu()
{
	if (L.last != -1)
	{
		printf("顺序表的长度为:\n\t\t%d\n", L.last + 1);
	}
	else
	{
		printf("\n\t\t顺序表为空!\n");
	}
}

void charu()
{
	if (L.last != -1)
	{
		int i = 0;
		int x = 0;
		if (L.last >= M)
		{
			printf("溢出!");
		}
		else
		{
			shuchu();
			printf("\n你想要在第几个数据处插入?\n");
			scanf_s("%d", &i);
			if ((i < 0) || (i > L.last + 1))
			{
				printf("出现错误!");
			}
			else
			{
				printf("输入待插入的数据\n");
				scanf_s("%d", &x);
				//移动元素位置(i为数据x将要插入的位置)
				for (int j = L.last; j >= i - 1; j--)
				{
					L.data[j + 1] = L.data[j];
				}
				//插入数据(x为插入数据)
				L.data[i - 1] = x;
				//表的最后一个元素的指向增加(当前表中实际存放元素数量)
				L.last++;
				shuchu();
			}
		}
	}
	else
	{
		printf("\n\t\t顺序表为空!\n");
	}
}

void shanchu()
{
	if (L.last != -1)
	{
		int i = 0, j = 0;
		shuchu();
		printf("\n你想要删除第几个数据?\n");
		scanf_s("%d", &i);
		if ((i<0) || (i>L.last + 1))
		{
			printf("出现错误!");
		}
		else
		{
			//移动元素位置(i为删除数据的位置)
			for (j = i; j <= L.last; j++)
			{
				L.data[j - 1] = L.data[j];
			}
			//表的最后一个元素的指向减小(当前表中实际存放元素数量)
			L.last--;
			shuchu();
		}
	}
	else
	{
		printf("\n\t\t顺序表为空!\n");
	}
}

void main()
{
	int b = 1, k;
	L.last = -1;
	while (b)
	{
		system("cls");
		printf("\n\n\t\t顺序表上的基本运算\n\n");
		printf("\t\t ----------------------------\n");
		printf("\t\t|1.... 顺序表数据输入       |\n");
		printf("\t\t|2.... 顺序表数据输出       |\n");
		printf("\t\t|3.... 顺序表数据置空       |\n");
		printf("\t\t|4.... 顺序表数据长度       |\n");
		printf("\t\t|5.... 顺序表数据插入       |\n");
		printf("\t\t|6.... 顺序表数据删除       |\n");
		printf("\t\t|0.... 退出                 |\n");
		printf("\t\t ----------------------------\n");
		printf("\t\t请选择:");
		scanf_s("%d", &k);
		switch (k)
		{
			case 1:   shuru();     break;
			case 2:   shuchu();    break;
			case 3:   zhikong();   break;
			case 4:   changdu();   break;
			case 5:   charu();     break;
			case 6:   shanchu();   break;
			case 0:	  b = 0;       break;
			default:printf("\n\t\t请输入正确的选择!\n");
		}
		if (b != 0) { printf("\n\t\t"); system("pause"); }
	}
	printf("\n\t\t谢谢使用!qwq\n\n\t\t");
}

如有错误,欢迎指正! _

参考文献:
数据结构:用C语言描述/唐策善等编著.-北京:高等教育出版社,1995(2011重印)


  1. 注意:typedef用法类似宏定义,意思和define相同,只是写法不同。typedef int datatype的作用在于在程序设计中,为了使一些复杂类型等更容易被理解、记忆,加速开发,而使用的一种技术。这相当于给一些类型一个别称,起到的作用都是相同的,此处就相当于给int类型起了一个别称叫datatype。1 ↩︎

猜你喜欢

转载自blog.csdn.net/qq_36260974/article/details/84175150