(C语言)实现顺序表的基本操作(注释很详细)

创建一个结构体用于存放顺序表相关数据

#define SEQTYPE int
typedef struct SeqList
{
	SEQTYPE* data;
	int size;		//有效数据个数
	int capacity;	//容量
}SeqList;

初始化顺序表

void SeqListInit(SeqList* pq)
{
	CheckNull(pq);

	pq->data = NULL;
	pq->capacity = 0;
	pq->size = 0;
}

插入元素

  1. 插入到表头;
  2. 插入到指定位置;
  3. 插入到尾部;

先检查容量是否够用

void CheckCapacity(SeqList* pq)
{
	CheckNull(pq);
	
	//如果空间满了,扩容
	if (pq->size >= pq->capacity)
	{
		int newcapacity = pq->capacity == 0 ? 4 : pq->capacity * 2;

		SEQTYPE* new = (SEQTYPE*)realloc(pq->data, sizeof(SEQTYPE) * newcapacity);
		if (new == NULL)
		{
			perror("realloc");
			exit(-1);
		}

		pq->data = new;
		pq->capacity = newcapacity;

	}
	puts("增容成功");
}

//往顺序表指定位置插入数据
void SeqListInsert(SeqList* pq, int pos)
{
	CheckNull(pq);
	assert(pos <= pq->size);
	SEQTYPE InsertVal;
	if (pos == -1)
	{
		printf("请分别输入添加的数据和位置,空格隔开:>");
		scanf("%d %d", &InsertVal, &pos);
		if (pos > pq->size)
		{
			printf("请正确输入\n");
			return;
		}
	}
	else
	{
		printf("请输入添加的数据:>");
		scanf("%d", &InsertVal);
	}
	//检查容量是否足够
	CheckCapacity(pq);


	//插入数据
	int end = pq->size;
	int begin = pos;

	while (begin < end)
	{
		pq->data[end] = pq->data[end - 1];
		--end;
	}
	pq->data[pos] = InsertVal;
	++pq->size;
	printf("添加成功\n");
}

//往顺序表末位置插入数据
void SeqListPushBack(SeqList* pq)
{
	CheckNull(pq);
	SeqListInsert(pq, pq->size);
}

//往顺序表首位置插入数据
void SeqListPushFront(SeqList* pq)
{
	CheckNull(pq);
	SeqListInsert(pq, 0);
}

删除元素

  1. 删除首元素;
  2. 删除指定位置元素;
  3. 删除尾部元素;
//从顺序表指定位置删除数据
void SeqListErase(SeqList* pq, int pos)
{
	CheckNull(pq);

	if (pos == -1)
	{
		printf("请输入要删除数据的位置:>");
		scanf("%d", &pos);
		if (pos < 0 || pos >= pq->size)
		{
			printf("请正确输入\n");
			return;
		}
	}

	int begin = pos;
	int end = pq->size - 1;
	while (begin < end)
	{
		pq->data[begin] = pq->data[begin + 1];
		++begin;
	}

	--pq->size;
	puts("删除成功");
}

//从顺序表末位置删除数据
void SeqListPophBack(SeqList* pq)
{
	CheckNull(pq);
	SeqListErase(pq, pq->size - 1);
}

//从顺序表首位置删除数据
void SeqListPophFront(SeqList* pq)
{
	CheckNull(pq);
	SeqListErase(pq, 0);
}

元素修改

  1. 找到目标元素;
  2. 直接修改该元素的值;
//修改顺序表指定位置数据
void SeqListModify(SeqList* pq)
{
	CheckNull(pq);
	int pos;
	SEQTYPE x;
	printf("请输入修改的位置和新的数据,空格隔开:>");
	scanf("%d %d", &pos, &x);
	if (pos < 0 && pos >= pq->size)
	{
		printf("请正确输入\n");
		return;
	}


	pq->data[pos] = x;
	puts("修改成功");
}

查找元素

  • 查找目标元素,算法多种,比如二分,插值等等,这里使用顺序查找算法,具体代码如下:
//查找所需数据是否存在顺序表中
void SeqListFindData(SeqList* pq)
{
	CheckNull(pq);
	SEQTYPE x;

	printf("请输入要查找的数据:>");
	scanf("%d", &x);

	for (int i = 0; i < pq->size; i++)
	{
		if (pq->data[i] == x)
		{
			printf("所需查询数据存在,下标为:>%d\n", i);
			return;
		}
	}
	printf("找不到\n");

}

排序元素

//排序顺序表
void SeqListSort(SeqList* pq)
{
	CheckNull(pq);

	int option = 0;
	printf("输入0为升序,1为降序:>");
	scanf("%d", &option);

	for (int i = 0; i < pq->size - 1; i++)
	{
		for (int j = 0; j < pq->size - i - 1; j++)
		{
			if (pq->data[j] > pq->data[j + 1])
			{
				SEQTYPE tmp = pq->data[j];
				pq->data[j] = pq->data[j + 1];
				pq->data[j + 1] = tmp;
			}
		}
	}

	if (option)
	{
		SeqListReverse(pq);
		return;
	}

}

元素反转

//顺序表反转
void SeqListReverse(SeqList* pq)
{
	CheckNull(pq);

	int left = 0;
	int right = pq->size - 1;

	while (left < right)
	{
		SEQTYPE tmp = pq->data[left];
		pq->data[left] = pq->data[right];
		pq->data[right] = tmp;
		++left;
		--right;
	}

}

源码

  • 以上是顺序表常用的功能操作,下面附上完整代码,VS2019环境

SeqList.c

#include "SeqList.h"


void CheckNull(SeqList* pq)
{
	if (pq == NULL)
	{
		perror("pq::");
		exit(-1);
	}
}

//初始化顺序表
void SeqListInit(SeqList* pq)
{
	CheckNull(pq);

	pq->data = NULL;
	pq->capacity = 0;
	pq->size = 0;
}


void SeqListDestory(SeqList* pq)
{
	CheckNull(pq);

	free(pq->data);
	pq->data = NULL;

	pq->size = 0;
	pq->capacity = 0;

}

void CheckCapacity(SeqList* pq)
{
	CheckNull(pq);
	
	//如果空间满了,扩容
	if (pq->size >= pq->capacity)
	{
		int newcapacity = pq->capacity == 0 ? 4 : pq->capacity * 2;

		SEQTYPE* new = (SEQTYPE*)realloc(pq->data, sizeof(SEQTYPE) * newcapacity);
		if (new == NULL)
		{
			perror("realloc");
			exit(-1);
		}

		pq->data = new;
		pq->capacity = newcapacity;

	}
	puts("增容成功");
}

void SeqListPrint(SeqList* pq)
{
	CheckNull(pq);
	if (pq->size == 0)
		printf("\n");
	else
	{
		for (int i = 0; i < pq->size; i++)
		{
			printf("%d ", pq->data[i]);
		}
		puts("\n--------------------------------------");
	}

}

//往顺序表末位置插入数据
void SeqListPushBack(SeqList* pq)
{
	CheckNull(pq);
	SeqListInsert(pq, pq->size);
}

//往顺序表首位置插入数据
void SeqListPushFront(SeqList* pq)
{
	CheckNull(pq);
	SeqListInsert(pq, 0);
}

//往顺序表指定位置插入数据
void SeqListInsert(SeqList* pq, int pos)
{
	CheckNull(pq);
	assert(pos <= pq->size);
	SEQTYPE InsertVal;
	if (pos == -1)
	{
		printf("请分别输入添加的数据和位置,空格隔开:>");
		scanf("%d %d", &InsertVal, &pos);
		if (pos > pq->size)
		{
			printf("请正确输入\n");
			return;
		}
	}
	else
	{
		printf("请输入添加的数据:>");
		scanf("%d", &InsertVal);
	}
	//检查容量是否足够
	CheckCapacity(pq);


	//插入数据
	int end = pq->size;
	int begin = pos;

	while (begin < end)
	{
		pq->data[end] = pq->data[end - 1];
		--end;
	}
	pq->data[pos] = InsertVal;
	++pq->size;
	printf("添加成功\n");

}

//从顺序表指定位置删除数据
void SeqListErase(SeqList* pq, int pos)
{
	CheckNull(pq);

	if (pos == -1)
	{
		printf("请输入要删除数据的位置:>");
		scanf("%d", &pos);
		if (pos < 0 || pos >= pq->size)
		{
			printf("请正确输入\n");
			return;
		}
	}

	int begin = pos;
	int end = pq->size - 1;
	while (begin < end)
	{
		pq->data[begin] = pq->data[begin + 1];
		++begin;
	}

	--pq->size;
	puts("删除成功");

}

//从顺序表末位置删除数据
void SeqListPophBack(SeqList* pq)
{
	CheckNull(pq);
	SeqListErase(pq, pq->size - 1);
}

//从顺序表首位置删除数据
void SeqListPophFront(SeqList* pq)
{
	CheckNull(pq);
	SeqListErase(pq, 0);
}

//修改顺序表指定位置数据
void SeqListModify(SeqList* pq)
{
	CheckNull(pq);
	int pos;
	SEQTYPE x;
	printf("请输入修改的位置和新的数据,空格隔开:>");
	scanf("%d %d", &pos, &x);
	if (pos < 0 && pos >= pq->size)
	{
		printf("请正确输入\n");
		return;
	}


	pq->data[pos] = x;
	puts("修改成功");
}

//查找顺序表指定位置数据
void SeqListFindPos(SeqList* pq)
{
	CheckNull(pq);
	int pos;
	printf("请输入要查找数据的位置:>");
	scanf("%d", &pos);
	if (pos < 0 && pos >= pq->size)
	{
		printf("请正确输入\n");
		return;
	}

	for (int i = 0; i < pq->size; i++)
	{
		if (pq->data[i] == pq->data[pos])
		{
			printf("查找位置的数据为:>%d\n", pq->data[pos]);
			break;
		}
	}

}

//查找所需数据是否存在顺序表中
void SeqListFindData(SeqList* pq)
{
	CheckNull(pq);
	SEQTYPE x;

	printf("请输入要查找的数据:>");
	scanf("%d", &x);

	for (int i = 0; i < pq->size; i++)
	{
		if (pq->data[i] == x)
		{
			printf("所需查询数据存在,下标为:>%d\n", i);
			return;
		}
	}
	printf("找不到\n");

}



//排序顺序表
void SeqListSort(SeqList* pq)
{
	CheckNull(pq);

	int option = 0;
	printf("输入0为升序,1为降序:>");
	scanf("%d", &option);

	for (int i = 0; i < pq->size - 1; i++)
	{
		for (int j = 0; j < pq->size - i - 1; j++)
		{
			if (pq->data[j] > pq->data[j + 1])
			{
				SEQTYPE tmp = pq->data[j];
				pq->data[j] = pq->data[j + 1];
				pq->data[j + 1] = tmp;
			}
		}
	}

	if (option)
	{
		SeqListReverse(pq);
		return;
	}

}


//顺序表反转
void SeqListReverse(SeqList* pq)
{
	CheckNull(pq);

	int left = 0;
	int right = pq->size - 1;

	while (left < right)
	{
		SEQTYPE tmp = pq->data[left];
		pq->data[left] = pq->data[right];
		pq->data[right] = tmp;
		++left;
		--right;
	}

}


test.c

#include "SeqList.h"



void menu()
{
	printf("######################################################\n");
	printf("#####       1.  Print        2.  Insert          #####\n");
	printf("#####       3.  PushFront    4.  PushBack        #####\n");
	printf("#####       5.  PopFront     6.  PopBack         #####\n");
	printf("#####       7.  FindPos      8.  FindData        #####\n");
	printf("#####       9.  Modify       10. Erase           #####\n");
	printf("#####       11. EMPTY        12. Sort            #####\n");
	printf("#####       13. Reverse      0.  Exit            #####\n");
	printf("######################################################\n");
}

enum Option
{
	EXIT,
	PRINT,
	INSERT,
	PUSHFRONT,
	PUSHBACK,
	POPFRONT,
	POPBACK,
	FINDPOS,
	FINDDATA,
	MODIFY,
	ERASE,
	EMPTY,
	SORT,
	REVERSE,
};

int main()
{
	int option = 0;
	int posi = -1;

	SeqList s;

	SeqListInit(&s);

	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &option);
		switch (option)
		{
		case PRINT:
			SeqListPrint(&s);
			break;

		case INSERT:
			SeqListInsert(&s, posi);
			break;

		case PUSHFRONT:
			SeqListPushFront(&s);
			break;

		case PUSHBACK:
			SeqListPushBack(&s);
			break;

		case POPFRONT:
			SeqListPophFront(&s);
			break;

		case POPBACK:
			SeqListPophBack(&s);
			break;

		case FINDPOS:
			SeqListFindPos(&s);
			break;

		case FINDDATA:
			SeqListFindData(&s);
			break;
		case MODIFY:
			SeqListModify(&s);
			break;

		case ERASE:
			SeqListErase(&s, posi);
			break;

		case EMPTY:
			SeqListDestory(&s);
			break;

		case SORT:
			SeqListSort(&s);
			break;

		case REVERSE:
			SeqListReverse(&s);
			break;

		case EXIT:
			SeqListDestory(&s);
			printf("退出\n");
			break;

		default:
			printf("请正确输入\n");
			break;
		}
	} while (option);

	return 0;
}

SeqList.h

#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <string.h>


//

#define SEQTYPE int
typedef struct SeqList
{
	SEQTYPE* data;
	int size;		//有效数据个数
	int capacity;	//容量
}SeqList;

//初始化顺序表
void SeqListInit(SeqList* pq);

//销毁顺序表
void SeqListDestory(SeqList* pq);

//打印顺序表
void SeqListPrint(SeqList* pq);

//往顺序表指定位置插入数据
void SeqListInsert(SeqList* pq, int pos);

//往顺序表末位置插入数据
void SeqListPushBack(SeqList* pq);

//往顺序表首位置插入数据
void SeqListPushFront(SeqList* pq);

//从顺序表指定位置删除数据
void SeqListErase(SeqList* pq, int pos);

//从顺序表末位置删除数据
void SeqListPophBack(SeqList* pq);

//从顺序表首位置删除数据
void SeqListPophFront(SeqList* pq);


//修改顺序表指定位置数据
void SeqListModify(SeqList* pq);


//查找顺序表指定位置数据
void SeqListFindPos(SeqList* pq);

//查找所需数据是否存在顺序表中
void SeqListFindData(SeqList* pq);

//排序顺序表
void SeqListSort(SeqList* pq);

//顺序表反转
void SeqListReverse(SeqList* pq);

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
非常感谢您的提问!以下是C语言顺序表基本操作代码实现,带有详细注释: ```c #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 // 定义顺序表的最大长度 typedef struct { int data[MAXSIZE]; // 存储元素的数组 int length; // 当前长度 } SqList; // 定义顺序表类型 // 初始化顺序表 void InitList(SqList *L) { L->length = 0; // 初始长度为0 } // 插入元素 int ListInsert(SqList *L, int i, int e) { if (i < 1 || i > L->length + 1) { // 判断插入位置是否合法 return 0; // 插入失败,返回0 } if (L->length >= MAXSIZE) { // 判断顺序表是否已满 return 0; // 插入失败,返回0 } for (int j = L->length; j >= i; j--) { // 将插入位置及之后的元素后移 L->data[j] = L->data[j - 1]; } L->data[i - 1] = e; // 插入新元素 L->length++; // 长度加1 return 1; // 插入成功,返回1 } // 删除元素 int ListDelete(SqList *L, int i, int *e) { if (i < 1 || i > L->length) { // 判断删除位置是否合法 return 0; // 删除失败,返回0 } *e = L->data[i - 1]; // 保存被删除的元素 for (int j = i; j < L->length; j++) { // 将删除位置之后的元素前移 L->data[j - 1] = L->data[j]; } L->length--; // 长度减1 return 1; // 删除成功,返回1 } // 查找元素 int LocateElem(SqList L, int e) { for (int i = 0; i < L.length; i++) { // 从前往后查找 if (L.data[i] == e) { return i + 1; // 返回元素在顺序表中的位置 } } return 0; // 未找到,返回0 } // 获取元素 int GetElem(SqList L, int i, int *e) { if (i < 1 || i > L.length) { // 判断获取位置是否合法 return 0; // 获取失败,返回0 } *e = L.data[i - 1]; // 获取元素 return 1; // 获取成功,返回1 } // 输出顺序表 void PrintList(SqList L) { for (int i = 0; i < L.length; i++) { printf("%d ", L.data[i]); } printf("\n"); } int main() { SqList L; InitList(&L); ListInsert(&L, 1, 1); ListInsert(&L, 2, 2); ListInsert(&L, 3, 3); ListInsert(&L, 4, 4); ListInsert(&L, 5, 5); printf("顺序表:"); PrintList(L); int e; ListDelete(&L, 3, &e); printf("删除第3个元素:%d\n", e); printf("顺序表:"); PrintList(L); printf("元素5的位置:%d\n", LocateElem(L, 5)); GetElem(L, 2, &e); printf("第2个元素:%d\n", e); return 0; } ``` 希望这个代码能够满足您的需求!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值