顺序表(静态开辟内存)

本文介绍了顺序表的实现及基本操作,包括插入、删除、排序等,通过具体代码展示了如何使用顺序表来管理通讯录数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# 简单实现顺序表


@ 本篇博客的顺序表类似于通讯录的静态实现<链接>: http://blog.youkuaiyun.com/bitboss/article/details/51374654

@ 本篇博客用到的冒泡排序方法: http://blog.youkuaiyun.com/bitboss/article/details/51192704


/*
顺序表功能:

  1.    EXIT, 退出
  2.  INSERT ,添加成员
  3.  SORT,排序所有成员
  4.  BINARYSEARCH,查找指定成员
  5.  REMOVE,删除指定成员
  6.  PUSHFRONT ,头插
  7.  PUSHBACK ,尾插
  8.  POPBACK,尾删
  9.  POPFRONT,头删
  10.  PRINTSEQLIST打印所有成员
  11. 清空所有成员
*/


@ 注意: 代码中有详细注释,请仔细阅读。

# 代码:

@   自定义头文件“SeqList.h”,包含各种声明:

#ifndef _SEQLIST_H__//防止头文件重定义
#define _SEQLIST_H__

#define _CRT_SECURE_NO_WARNINGS 1//消除scanf的警告
#include<stdio.h>
#include<stdlib.h>

#define MAX 100
enum Select
{
	EXIT,
	INSERT ,
	SORT,
	BINARYSEARCH,
	REMOVE,
	PUSHFRONT ,
	PUSHBACK ,
	POPBACK,
	POPFRONT,
	PRINTSEQLIST
};
typedef int DataType;//数据可以是int也可以是char,为方便修改可以在这里进行类型重定义
                     //注意的是,代码里的%d,%c接收和输出要与类型一致;
typedef struct SepLish
{
	DataType Data[MAX];//最大容量预定义为MAX = 100;
	int sz;
}SeList,*pSepList;

void InitSeqList(pSepList pSeq);//初始化

void PrintSeqList(pSepList pSeq);//打印

void PopFront(pSepList pSeq);//头删
void PopBack(pSepList pSeq);//投插
void Sort(pSepList pSeq);//冒泡排序
void PushBack(pSepList pSeq, DataType x);//尾插
void PushFront(pSepList pSeq,DataType x);//头删
void BinarySerach(pSepList pSeq,DataType x);//查找
void Remove(pSepList pSeq,DataType x);//删除
void Insert(pSepList pSeq,int pos,DataType x);//插入
void Exit();

void test();

#endif  //_SEQLIST_H__

@ 函数功能实现部分:

#include"SeqList.h"

void Judge_full(pSepList pSeq)//包装一个公用函数;
{
	if(pSeq ->sz >= MAX)
	{
		printf("out of memery\n");
		return ;
	}
}//判断容量是否已满


void PrintSeqList(pSepList pSeq)//打印所有数据;
{
	int i = 0;
	printf("*************************************************\n\n");
	printf("以下为所有数据:> ");
	for(;i < pSeq ->sz ;i++)
	{
		printf("%d ",pSeq ->Data[i]);
	}
	printf("\n\n*************************************************\n");
}//打印

void InitSeqList(pSepList pSeq)//初始化顺序表;
{
	int i = 0;
	pSeq ->sz = 0;
	for(; i < MAX; i++)
		pSeq ->Data [i] = 0;
	
}//初始化

void PushBack(pSepList pSeq, DataType x)//从最后加入成员
{
	Judge_full(pSeq);
	pSeq ->Data [pSeq ->sz++] = x;

	printf("\n^^^^^^添加成功^*^^^^^^^^^\n\n");
}//尾插

void PopBack(pSepList pSeq)//从最后删除一个成员
{
	pSeq ->sz --;
	printf("\n*** 删除成功 ***\n\n");
}//尾删

void PushFront(pSepList pSeq,DataType x)//在第一个位置加入元素;
{
	int i = pSeq ->sz;
	Judge_full(pSeq);
	
	for(;i >=0; i--)
	{
		pSeq ->Data [i] = pSeq ->Data [i - 1];//在空间足够的情况下,所有元素向后挪动一个位置
	}
	pSeq ->Data [0] = x;
	printf("\n^^^^^^添加成功^*^^^^^^^^^\n\n");
	pSeq ->sz ++;
}//头插

void PopFront(pSepList pSeq)//删除第一个位置的元素;
{
	int i = 0;
	if(pSeq ->sz == 1)//只有一个元素的话直接将sz置为0即可;
	{
		pSeq ->sz = 0;
	}
	else
	{
		for(i = 0; i < pSeq ->sz ; i++)
		{
			pSeq ->Data [i] = pSeq ->Data [i + 1];//从第二个人元素开始,所有元素向前挪动一个位置;
		}
	}
	printf("\n*** 删除成功 ***\n\n");
	pSeq ->sz --;
}//头删

void Insert(pSepList pSeq,int pos,DataType x)//指定位置加入一个成员;
{
	int i = pSeq ->sz ;
	if(pos > i+1)//注意要对指定为值进行判断,该位置是否合理;
	{
		printf("选择位置有误\n");
		return ;
	}

	Judge_full(pSeq);
	for(;i >=pos; i--)
	{
		pSeq ->Data [i] = pSeq ->Data [i - 1];//挪动下表为pos开始往后所有元素;
	}
	pSeq ->Data [pos - 1] = x;
	printf("\n^^^^^^添加成功^*^^^^^^^^^\n\n");
	pSeq ->sz ++;
}//插入

int find_X(pSepList pSeq,DataType x)//包装的公用查找函数;
{
	int i = 0;
	/* 这里其实有个问题我没处理,在删除那里也会出现,就是有重复元素的情况,
	有兴趣的同学可以补全一下;
	*/
	for(; i < pSeq ->sz ; i++)
	{
		if(pSeq ->Data [i] == x)
			return i;
	}
	return -1;
}//单独包装的查找函数

void BinarySerach(pSepList pSeq,DataType x)//查找指定成员;
{
	int index = find_X(pSeq,x);//直接调用公用查找函数

	if(index >= 0)
	 printf("\n***查找到的结果:%d ***\n\n",pSeq->Data [index]);
	else
		printf("\n***没找到该内容***\n\n");
}//查找

void Remove(pSepList pSeq,DataType x)//删除指定元素;
{
	//有兴趣的同学可以在加一个功能,删除指定位置的元素,更为合理;
	int i = 0;
	int j = 0;

	if(pSeq ->sz == 0)
		pSeq ->sz  = 0;
	else
	{
		for(j = 0; j < pSeq ->sz ; )
			if(pSeq ->Data [j] == x)
			{
				for(i = j; i < pSeq ->sz ; i++)
				{
					pSeq ->Data [i] = pSeq ->Data [i + 1];
				}
				pSeq ->sz --;
			}
			else
				j++;
	printf("\n*** 删除成功 ***\n\n");
	}

}//删除

void Sort(pSepList pSeq)//冒泡排序所有元素
{
	int i = 0;
	int j = 0;

	for(i = 0; i < pSeq->sz  - 1; i++)
	{
		for(j = 0; j < pSeq->sz  - i - 1; j++)
		{
			int tmp = 0;
			if(pSeq->Data [j] > pSeq ->Data [j+1] )
			{
				tmp = pSeq ->Data [j];
				pSeq ->Data [j] = pSeq ->Data [j+1];
				pSeq ->Data [j+1] = tmp;
			}
		}
	}
}//冒泡

void Exit()//退出
{
	exit(0);
}

void Print_Select()//打印菜单
{
	    printf("    *******功能表*******\n");
		printf("*******1.插入数据    *******\n");
		printf("*******2.排序        *******\n");
		printf("*******3.查找        *******\n");
		printf("*******4.删除        *******\n");
		printf("*******5.顶部插入数据*******\n");
		printf("*******6.尾部插入数据*******\n");
		printf("*******7.尾部部删除数据*******\n");
		printf("*******8.顶部删除数据*******\n");
		printf("*******9.打印所有数据*******\n");
		printf("*******10.清空所有数据*******\n");
		printf("*******0.退出        *******\n");
		printf("****************************\n");
}

void test()//接下来就是选择了
{
	int select = 0;
	SeList pon;
	InitSeqList(&pon);
	
	while(1)
	{
	Print_Select();
	printf("\n***当前有成员:%d 个***\n\n",pon.sz );
	printf("请输入选择:> ");
	scanf("%d",&select );

	if(select >= 0 || select <= 10)
	{
		int data = 0;
		int pos = 0;
		switch(select)
		{
		case INSERT:
			printf("请输入要加入成员的位置:>");
			scanf("%d",&pos);
			printf("请输入要加入的成员:>");
			scanf("%d",&data);
			Insert(&pon,pos,data);
			break;
		case SORT:
			Sort(&pon);
			break;
		case BINARYSEARCH:
			printf("请输入需要查找的成员:> ");
			scanf("%d",&data);
			BinarySerach (&pon,data);
			break;
		case REMOVE:
			printf("请输入需要删除的成员:> ");
			scanf("%d",&data);
			Remove(&pon,data);
			break;
		case PUSHFRONT:
			printf("请输入需要加入的成员:> ");
			scanf("%d",&data);
			PushFront(&pon,data);
			break;
		case PUSHBACK:
			printf("请输入需要加入的成员:> ");
			scanf("%d",&data);
			PushBack (&pon,data);
			break;
		case POPBACK:
			PopBack (&pon);
			break;
		case POPFRONT:
			PopFront (&pon);
			break;
		case PRINTSEQLIST :
			PrintSeqList(&pon);
			break;
		case 10:
			pon.sz  = 0;
			break;
		case EXIT:
			Exit();
			break;
		default:
			printf("\n*** 输入选项有误: >_< ***\n\n");
			break;
		}
	}
	else
		printf("\n*** 输入选项有误: >_< ***\n\n");
	}
}


@ 主函数部分:

#include"SeqList.h"

int main()
{
	test();
	system("pause");
	return 0;
}

The End!

### 关于顺序表的数据结构图解与说明 #### 什么是顺序表顺序表是一种线性数据结构,其中的元素按照逻辑顺序依次存储在连续的内存空间中。这种特性使得顺序表支持通过索引快速访问任意位置上的元素。 #### 静态顺序表 静态顺序表通常使用数组来实现,其大小固定,在创建时即已确定。由于无法动态调整容量,因此适用于场景较为固定的场合[^2]。 #### 动态顺序表 动态顺序表则允许在运行过程中根据需求扩展或缩减存储空间。它一般由一个指针指向实际分配的空间,并维护当前长度和最大容量两个属性。以下是动态顺序表的一个典型定义: ```c typedef struct _tag_SeqList { int length; // 当前有效元素数量 int capacity; // 总容量 unsigned int *node; // 存储节点的实际地址 } TSeqList; ``` 此结构体中的 `length` 表示当前列表的有效元素数目;而 `capacity` 则表示该列表的最大容纳能力;最后,`*node` 是指向一块连续内存区域的指针,用于保存具体的数据项[^1]。 #### 基本操作及其图解 ##### 开辟并初始化一个动态顺序表 当新建一个顺序表实例时,需为其分配初始大小的内存块,并设置默认参数值(如长度为0)。这一步骤确保了后续可以正常执行其他功能函数。 ##### 扩展顺序表容量 如果尝试向满载状态下的顺序表追加新成员,则先要申请更大的备用区段替换旧有部分,再复制原有内容到新的地方完成迁移过程之后才能继续增加项目数目的动作。 ##### 尾部插入/删除元素 对于尾端的操作比较简单高效——只需改变最后一个可用槽位所对应的数值即可达成目标效果(注意同步更新相关计数器变量)。 ##### 头部或者中间指定位置处进行增删处理 这类情况相对复杂些因为涉及到整体序列重新排列的问题所以时间开销也较大一些不过仍然保持O(n)级别的时间复杂度范围内运作良好。 ##### 销毁以及展示全部记录信息 释放之前占用过的资源防止泄露同时提供方法让用户能够查看整个集合内部状况以便调试验证等功能得以顺利开展下去. ##### 查找特定条件满足的对象并实施相应更改措施 遍历整个链条直至找到符合条件的目标为止然后依据实际情况作出适当反应比如返回匹配成功的下标位置或者是直接替换成另外的新值得方式来进行管理控制流程走向等等不一而足取决于具体应用场景的需求差异所在之处各有千秋各取所需罢了. 以上就是有关顺序表这一经典基础型抽象数据类型的全面解析介绍希望能够帮助大家更好地理解和掌握相关内容知识点谢谢!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值