c++实现顺序表的基本操作

顺序表

数组描述方法将元素存储在一个数组中,用一个数学公式来确定每个元素存储的位置,即在数组中的索引。这是最简单的一种存储方式,所有元素依次存储在一片连续的存储空间中,这就是通常所说的顺序表。   ---   数据结构、算法与应用 


顺序表的实现

 线性表动态分配顺序存储结构

ps:为了方便修改数据元素的类型,使用了模板,可以方便修改线性表中的数据元素的类型;

#define LIST_INIT_SIZE 100     // 线性表存储空间的初始分配量

#define LISTNCREMENT 10        // 线性表存储空间的分配增量

template <class T>
struct SeqList
{
	T* element;        // 存储空间的基质
	int capacity;      // 线性表的当前分配的存储容量
	int listSize;;     // 线性表的当前长度
};

顺序表的基本操作 

void initMenu();            // 初始化菜单
SeqList<int>* initList();             // 初始化线性表
bool distroyList(SeqList<int>*&);     // 销毁线性表
bool clearList(SeqList<int>*&);       // 清空线性表
bool isEmpty(SeqList<int>*&);         // 判断是否为空
int getLength(SeqList<int>*&);        // 得到线性表的当前长度
int getElement(SeqList<int>*&, int);            // 得到指定位置的元素
int getIndex(SeqList<int>*&, int);              // 得到元素的下标
int getPreElement(SeqList<int>*&, int);         // 得到元素的前驱
int getSeqElement(SeqList<int>*&, int);         // 得到元素的后继
bool insertElement(SeqList<int>*&, int, int);   // 插入元素
bool deleteElement(SeqList<int>*&, int);        // 删除元素
void showElement(SeqList<int>*&);               // 遍历表中的所有元素
void megerList(SeqList<int>*&, SeqList<int>*&); // 合并两个线性表

自定义函数的实现

void initMenu()    // 初始化菜单界面
{
    cout << "*************************" << endl;
    cout << "1---初始化线性表" << endl;
    cout << "2---销毁线性表" << endl;
    cout << "3---清空线性表" << endl;
    cout << "4---判断线性表是否为空" << endl;
    cout << "5---求线性表的长度" << endl;
    cout << "6---获取线性表中指定位置的元素" << endl;
    cout << "7---获取线性表元素的位置" << endl;
    cout << "8---求前驱" << endl;
    cout << "9---求后继" << endl;
    cout << "10---在线性表指定位置插入元素" << endl;
    cout << "11---删除线性表指定位置的元素" << endl;
    cout << "12---显示线性表" << endl;
    cout << "13---合并两个非递减有序的线性表" << endl;
    cout << "14---退出程序(输入负数)" << endl;
    cout << "*************************" << endl;
}

(1)线性表的初始化

初始化线性表,是指初始化一个空的线性表,里面的元素个数是0 

SeqList<int>* initList()        // 初始化线性表
{
	SeqList<int>* MyList = new SeqList<int>();
	try
	{
		MyList->element = new int[LIST_INIT_SIZE];
		MyList->capacity = LIST_INIT_SIZE;
		MyList->listSize = 0;
	}
	catch (bad_alloc)
	{
		cerr << "初始化失败!" << endl;
		exit(1);
	}

	cout << "初始化成功!" << endl;
	return MyList;
}

(2)销毁线性表 、清空线性表、判断是否为空、返回线性表的长度

销毁线性表:释放线性表的基地址,将capacity与listSize赋值为0

清空线性表:只需将listSize赋值为0

判断是否为空:只需判断listSize的值是否为0

返回线性表的长度:只需将listSize的值返回

bool distroyList(SeqList<int>*& arrayList)    // 销毁线性表

{
	bool isDistory = false;
	delete arrayList->element;
	arrayList->element = nullptr;
	arrayList->capacity = 0;
	arrayList->listSize = 0;
	if (arrayList->element == nullptr)
	{
		isDistory = true;
	}
	return isDistory;
}

bool clearList(SeqList<int>*& arrayList)    // 清空线性表
{
	bool isClear = false;
	arrayList->listSize = 0;
	if (arrayList->listSize == 0)
	{
		isClear = true;
	}
	return isClear;
}

bool isEmpty(SeqList<int>*& arrayList)    // 判断线性表是否为空
{
	if (arrayList->listSize > 0)
	{
		return false;
	}
	return true;
}

int getLength(SeqList<int>*& arrayList)    // 得到线性表的当前长度
{
	return arrayList->listSize;
}

(3)获得对应位置的元素 

int getElement(SeqList<int>*& arrayList, int index)     // 得到对应位置的元素
{
	if (index > arrayList->listSize || index < 0)       // 判断用户输入的下标是否合法
	{
		return -1;
	}
	return arrayList->element[index - 1];
}

(4)获得线性表元素的下标 

int getIndex(SeqList<int>*& arrayList, int num)    // 得到元素的下标
{
	for (int i = 0; i < arrayList->listSize; i++)
	{
		if (arrayList->element[i] == num)
		{
			return i;
		}
	}
	return -1;
}

(5)获得前驱 

遍历顺序表找到与用户输入元素相同的元素的下标,将该下标-1得到前驱,但要注意特殊情况即当该元素为第一个元素时,没有前驱。

int getPreElement(SeqList<int>*& arrayList, int num)     // 得到元素的前驱
{
	int temp = -2;    // 用来记录元素前驱的下标
	for (int i = 0; i < arrayList->listSize; i++)
	{
		if (arrayList->element[i] == num && i == 0)
		{// 顺序表的第一个元素,没有前驱
			return -1;
		}
		if (arrayList->element[i] == num)
		{// 找到前驱
			temp = i - 1;
			break;
		}
	}
	if (temp == -2)
	{// 没有该元素
		return -2;
	}
	return arrayList->element[temp];
}

(6)获得后继

遍历顺序表找到与用户输入元素相同的元素的下标,将该下标+1得到后继,但要注意特殊情况即当该元素为最后一个元素时,没有后继。 

int getSeqElement(SeqList<int>*& arrayList, int num)    // 得到元素的后继
{    
	int temp = -2;     // 用来记录元素前驱的下标
	for (int i = 0; i < arrayList->listSize; i++)
	{
		if (arrayList->element[i] == num && i == arrayList->listSize - 1)
		{// 顺序表的最后一个元素,没有后继
			return -1;
		}
		if (arrayList->element[i] == num)
		{// 找到后继
			temp = i + 1;
			break;
		}
	}
	if (temp == -2)
	{// 没有该元素
		return -2;
	}
	return arrayList->element[temp];
}

(7)插入元素

插入元素之前要判断线性表是否初始化(主函数中实现),插入的位置是否合法,顺序表是否已满。

在顺序表的第i个位置插入元素e,与数组的插入操作基本相同,将顺序表第i个位置之后的元素从后向前依次向后移动一个位置,然后将元素e插入第i个位置,在插入元素之后要将顺序表的当前长度listSize++,但要注意是从后往前依次移动元素,即:先移动最后一个元素,在移动倒数第二个元素,依次类推

bool insertElement(SeqList<int>*& arrayList, int index, int num)    // 插入元素
{
	if (index < 1 || index > arrayList->listSize + 1)    // 判断插入的位置是否合法
	{
		return false;
	}
	if (arrayList->listSize >= arrayList->capacity)    // 判断顺序表的空间是否已满
	{
		try
		{
			int* newbase = new int[LIST_INIT_SIZE + LISTNCREMENT];    // 重新分配新的空间
			copy(arrayList->element, arrayList->element + LIST_INIT_SIZE, newbase);    // 将顺序表的元素赋值给新的顺序表
			arrayList->element = newbase;
			arrayList->capacity += LISTNCREMENT;
		}
		catch (bad_alloc)
		{
			exit(OVERFLOW);
		}
	}
	for (int i = arrayList->listSize - 1; i >= index - 1; i--)    // 插入操作,同数组的插入
	{
		arrayList->element[i + 1] = arrayList->element[i];
	}
	arrayList->element[index - 1] = num;
	arrayList->listSize++;
	return true;
}

(8)删除元素

删除元素之前要判断线性表是否初始化(主函数实现),顺序表是否为空(主函数实现),删除的位置是否合法。

删除线性表中的第i个元素,与数组的删除操作基本相同,需要将表中第i个元素之后的元素依次向前移动一位,将前面的元素覆盖。移动元素时要将第i+1个元素移动到第i个位置,在将第i+2个元素移动i+1的位置,直到将最后一个元素移动到它的前一个位置,删除元素之后,将顺序表的当前长的listSize--;

bool deleteElement(SeqList<int>*& arrayList, int index)     // 删除下表对应的元素

{
	if (index < 1 || index > arrayList->listSize)    // 判断用户输入的下标是否合法
	{
		return false;
	}

	for (int i = index - 1; i < arrayList->listSize; i++)    // 删除操作,同数组的删除
	{
		arrayList->element[i] = arrayList->element[i + 1];
	}
	arrayList->listSize--;
	return true;
}

(9)遍历线性表 

void showElement(SeqList<int>*& arrayList)    // 遍历线性表
{
	cout << "该线性表的元素为:" << endl;
	for (int i = 0; i < arrayList->listSize; i++)
	{
		cout << arrayList->element[i] << "\t";
	}
	cout << endl;
}

(10)合并两个非降序线性表

ps:该方法也是我自己在力扣上做题的时候学的,下面附上该方法的链接

画解算法:88. 合并两个有序数组

void megerList(SeqList<int>*& arrayList, SeqList<int>*& myList)    // 合并两个线性表
{    // myList 线性表在调用该函数前需要初始化,具体实现在主函数
	int size1 = arrayList->listSize;    // 记录arrayList的空间大小
	int size2 = myList->listSize;       // 记录myArray的空间大小
	int len1 = size1 - 1;               
	int len2 = size2 - 1;
	int len = size1 + size2 - 1;
    // 以上声明均为了更方便的实现一下操作

    // 合并两个非降序线性表前需要将两个线性表非降序排序
	sort(arrayList->element, arrayList->element + size1);
	sort(myList->element, myList->element + size2);

	SeqList<int>* newList = new SeqList<int>();    // 新的线性表,用来存储两个线性表合并后的新表
	newList->element = new int[size1 + size2]{ -1 };
	newList->listSize = size1 + size2;

	while (len1 >= 0 && len2 >= 0)    // 合并两个线性表的具体实现
	{
		newList->element[len--] = arrayList->element[len1] > myList->element[len2] ? arrayList->element[len1--] : myList->element[len2--];
	}

	if (len1 >= 0)
	{
		copy(arrayList->element, arrayList->element + (len1 + 1), newList->element);
	}
	if (len2 >= 0)
	{
		copy(myList->element, myList->element + (len2 + 1), newList->element);
	}

	cout << "合并后的顺序表为:" << endl;
	for (int i = 0; i < newList->listSize; i++)
	{
		cout << newList->element[i] << "\t";
	}
	cout << endl;
}

主函数的实现

int main()
{
	initMenu();
	SeqList<int>* arrayList = new SeqList<int>();

	int choice;
	cout << "请输入操作代码:";
	cin >> choice;

	while (choice > 0)
	{
		switch (choice)
		{
		case 1://初始化线性表空间
		{
			arrayList = initList();
			break;
		}
		case 2://销毁线性表
		{
			bool isTrue = distroyList(arrayList);
			if (isTrue)
			{
				cout << "销毁成功!" << endl;
			}
			else
			{
				cout << "销毁失败!" << endl;
				exit(1);
			}
			break;
		}
		case 3://清空线性表
		{
			bool isTrue = clearList(arrayList);
			if (isTrue)
			{
				cout << "清空成功!" << endl;
			}
			else
			{
				cout << "清空失败!" << endl;
				exit(1);
			}
			break;
		}
		case 4://判断线性表是否为空
		{
			bool isTrue = isEmpty(arrayList);
			if (isTrue)
			{
				cout << "该表为空" << endl;
			}
			else
			{
				cout << "该表不为空" << endl;
			}
			break;
		}
		case 5://求线性表的长度
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			cout << "线性表的长度为:" << getLength(arrayList) << endl;
			break;
		}
		case 6://获取线性表中指定位置的元素
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "请先为顺序表添加元素!" << endl;
				break;
			}
			int index;
			cout << "请输入要查找元素的位置:";
			cin >> index;
			int temp = getElement(arrayList, index);
			if (temp == -1)
			{
				cerr << "访问越界!" << endl;
			}
			else
			{
				cout << "该元素为:" << temp << endl;
			}
			break;
		}
		case 7://获取线性表元素的位置
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "请先为顺序表添加元素!" << endl;
				break;
			}
			int num;
			cout << "请输入您要查找的元素:";
			cin >> num;
			int temp = getIndex(arrayList, num);
			if (temp == -1)
			{
				cerr << "线性表中没有该元素!" << endl;
			}
			else
			{
				cout << "该元素的下标为:" << temp << endl;
			}
			break;
		}
		case 8://求前驱
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "请先为顺序表添加元素!" << endl;
				break;
			}
			int num;
			cout << "请输入求前驱的元素:";
			cin >> num;
			int temp = getPreElement(arrayList, num);
			if (temp == -1)
			{
				cout << "该元素没有前驱!" << endl;
			}
			else if (temp == -2)
			{
				cerr << "线性表中没有该元素!" << endl;
			}
			else
			{
				cout << "该元素的前驱为:" << temp << endl;
			}
			break;
		}
		case 9://求后继
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "请先为顺序表添加元素!" << endl;
				break;
			}
			int num;
			cout << "请输入求后继的元素:";
			cin >> num;
			int temp = getSeqElement(arrayList, num);
			if (temp == -1)
			{
				cout << "该元素没有后继!" << endl;
			}
			else if (temp == -2)
			{
				cerr << "线性表中没有该元素!" << endl;
			}
			else
			{
				cout << "该元素的后继为:" << temp << endl;
			}
			break;
		}
		case 10://在线性表指定位置插入元素
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			int index, num;
			cout << "请输入要插入的位置下标与元素(end of -1):";
			cin >> index >> num;
			while (index != -1)
			{
				bool isTrue = insertElement(arrayList, index, num);
				if (!isTrue)
				{
					cerr << "错误插入!" << endl;
					exit(1);
				}
				else
				{
					cout << "插入成功!" << endl;
					cout << "请输入要插入的位置下标与元素(end of -1):";
					cin >> index >> num;
				}
			}
			break;
		}
		case 11://删除线性表指定位置的元素
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "该顺序表已空!" << endl;
				break;
			}
			int index;
			cout << "请输入要删除的位置:";
			cin >> index;
			bool isTrue = deleteElement(arrayList, index);
			if (!isTrue)
			{
				cerr << "删除失败!" << endl;
				exit(1);
			}
			else
			{
				cout << "删除成功!" << endl;
			}
			{}
			break;
		}
		case 12://显示线性表
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "请先为顺序表添加元素!" << endl;
				break;
			}
			showElement(arrayList);
			break;
		}
		case 13://合并两个非递减有序的线性表
		{
			if (arrayList->element == nullptr)
			{
				cout << "请先初始化顺序表!" << endl;
				break;
			}
			if (isEmpty(arrayList))
			{
				cout << "请先为顺序表添加元素!" << endl;
				break;
			}
			cout << "自动创建一个新的线性表!" << endl;
			SeqList<int>* myList = initList();
			int index, num;
			cout << "请输入要插入的位置下标与元素(end of -1):";
			cin >> index >> num;
			while (index != -1)
			{
				insertElement(myList, index, num);
				cout << "请输入要插入的位置下标与元素(end of -1):";
				cin >> index >> num;
			}
			megerList(arrayList, myList);
			break;
		}
		default:
			break;
		}
		Sleep(1000);
		system("cls");
		initMenu();
		cout << "请输入操作代码:";
		cin >> choice;
	}
	cout << "程序退出!" << endl;
	return 0;
}

注:本人已测试过该代码,如要亲自测试该代码,请添加头文件

#include <iostream>
#include <algorithm>
#include <Windows.h>

最后:

本人是第一次发表文章,以上代码仅为个人写法,不喜勿喷,如有不足或错误的地方欢迎指正。如果文章对你有所帮助,欢迎点赞支持。欢迎转载。

  • 9
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我可以为你介绍一下用C语言实现顺序基本操作的方法:首先,你需要编写一个函数来初始化顺序,这样才能确保顺序的大小正确;接着,你可以实现插入、删除、查找以及更新操作;最后,你可以创建一个函数来遍历顺序,以打印出中的所有元素。 ### 回答2: 顺序是一种线性数据结构,可以通过数组来实现。在C语言中,可以使用结构体来定义顺序,并编写相应的基本操作函数。 首先,我们可以定义一个结构体来顺序,其中包含一个指向数组的指针和记录当前线性长度的变量。例如: ``` #define MAX_SIZE 100 typedef struct{ int* data; int length; } SeqList; ``` 接下来,我们可以实现一些基本操作函数,包括初始化顺序、插入元素、删除元素、查找元素和打印顺序等。 1. 初始化顺序 ```c void init(SeqList* list){ list->data = (int*)malloc(MAX_SIZE * sizeof(int)); list->length = 0; } ``` 2. 插入元素 ```c void insert(SeqList* list, int element, int position){ if(position < 0 || position > list->length){ printf("插入位置错误"); return; } if(list->length == MAX_SIZE){ printf("顺序已满"); return; } for(int i = list->length; i > position; i--){ list->data[i] = list->data[i - 1]; } list->data[position] = element; list->length++; } ``` 3. 删除元素 ```c void remove(SeqList* list, int position){ if(position < 0 || position >= list->length){ printf("删除位置错误"); return; } for(int i = position + 1; i < list->length; i++){ list->data[i - 1] = list->data[i]; } list->length--; } ``` 4. 查找元素 ```c int search(SeqList* list, int element){ for(int i = 0; i < list->length; i++){ if(list->data[i] == element){ return i; } } return -1; } ``` 5. 打印顺序 ```c void print(SeqList* list){ for(int i = 0; i < list->length; i++){ printf("%d ", list->data[i]); } printf("\n"); } ``` 通过以上的操作函数,我们就可以使用C语言实现顺序基本操作了。使用这些操作函数,可以方便地对顺序进行插入、删除、查找和打印等操作。 ### 回答3: 顺序是一种线性的存储结构,它的特点是元素在存储空间中是连续地存放的。以下是用C语言实现顺序基本操作的步骤: 1. 定义顺序的结构体 首先要定义一个结构体来顺序,结构体中包括存放元素的数组和当前元素个数等信息。 ```c #define MAX_SIZE 100 // 顺序的最大容量 typedef struct { int data[MAX_SIZE]; // 存放元素的数组 int length; // 当前元素个数 } SeqList; ``` 2. 初始化顺序 定义一个初始化顺序的函数,将顺序的长度初始化为0。 ```c void initSeqList(SeqList *list) { list->length = 0; } ``` 3. 插入元素 定义一个插入元素的函数,根据位置和元素的值将元素插入到顺序中。 ```c int insertSeqList(SeqList *list, int pos, int value) { if (pos < 1 || pos > list->length + 1) { return 0; // 插入位置非法 } if (list->length >= MAX_SIZE) { return -1; // 顺序已满,无法插入新元素 } for (int i = list->length; i >= pos; i--) { list->data[i] = list->data[i-1]; // 元素后移 } list->data[pos-1] = value; // 在指定位置插入元素 list->length++; // 元素个数加1 return 1; // 插入成功 } ``` 4. 删除元素 定义一个删除元素的函数,根据位置删除顺序中的元素。 ```c int deleteSeqList(SeqList *list, int pos) { if (pos < 1 || pos > list->length) { return 0; // 删除位置非法 } for (int i = pos - 1; i < list->length-1; i++) { list->data[i] = list->data[i+1]; // 元素前移 } list->length--; // 元素个数减1 return 1; // 删除成功 } ``` 5. 查找元素 定义一个查找元素的函数,根据元素的值查找顺序中是否存在该元素,并返回其位置。 ```c int searchSeqList(SeqList *list, int value) { for (int i = 0; i < list->length; i++) { if (list->data[i] == value) { return i+1; // 返回元素位置 } } return 0; // 未找到该元素 } ``` 以上就是用C语言实现顺序基本操作的步骤。通过这些函数,我们可以实现顺序的初始化、插入、删除和查找等操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值