顺序表的基本操作

筅森魡賤 提交于 2019-12-02 05:16:30

今天和大家分享一下顺序表的基本操作

编写一个完整的程序,实现顺序表的建立、插入、删除、输出等基本运算。
(1) 建立一个顺序表,含有n个数据元素。
(2) 输出顺序表及顺序表的长度
(3) 在顺序表中删除值为x的结点或者删除给定位置i的结点。
(4) 将顺序表就地逆置,即利用原表的存储空间将线性表(a1,a2,...,an)逆置为(an,an-1,...,a1)。
(5) 将顺序表按升序排序。
(6) 设顺序表中的数据元素递增有序,将x插入到顺序表的适当位置上,以保持该表的有序性。
(7) 在主函数中设计一个简单的菜单,分别测试上述算法。

根据上题,我写了一个完整的程序,包括三个头文件,一个源程序。

头文件1(包括一些库文件):

#include <iostream>
#include <stdlib.h>
using namespace std;
头文件2(一些基本定义):

#define INIT_SIZE 100
#define INCRE 20
#define ERROR 0
#define OK 1

typedef int Status;
typedef int ElemType;
typedef struct SqList
{
	ElemType *elem;//顺序表头,
	int length;//顺序表中含有数据的个数
	int listsize;//顺序表的长度(注意与length的区别)
};
头文件3(一些基本函数的实现),我将分别将每个函数列出来,因为有一些需要注意的点。
创建顺序表:

Status Init(SqList &L)//
{
	int i;
	ElemType value;
	L.elem = (ElemType *)malloc(INIT_SIZE*sizeof(ElemType));
	if (!L.elem)
	{
		cout<<"分配内存失败!!!!!"<<endl;
		return ERROR;
	}
	L.listsize = INIT_SIZE;//表创建成功了,一定要记得将表长置为INIT_SIZE
	cout<<"提示:下面你可以开始输入数据了,输入-1表示输入结束"<<endl;
	cin>>value;
	for (i = 0;value != -1;i++)
	{
		L.elem[i] = value;
		cin>>value;
	}
	cout<<"提示:输入结束"<<endl;
	L.length = i;//表中的数据个数正好是此时的i
	return OK;
}
打印顺序表:

我这里使用一个length变量来接受表的长度

Status PrintList(SqList L,int &length)
{
	int i;
	for (i = 0;i<L.length;i++)
	{
		cout<<L.elem[i]<<endl;
	}
	length = L.length;
	cout<<"表长为"<<length<<endl;
	return OK;
}

删除数据:

根据题目,我这里写了两种删除数据的方式,值得一提的是,在第二种删除数据方式中,最好是采用二分法来确定被删除数据的位置,这样在一些比较大型的数据中,可以大大的提升效率。

Status Del(SqList &L)
{
	if (L.length == 0)//先判断表是否为空
	{
		cout<<"该表为空,不能进行删除操作"<<endl;
		return ERROR;
	}
	int choice;
	cout<<"你将要进行删除操作,请选择下一步操作内容:"<<endl;
	cout<<"1.删除表中某一位置的元素"<<endl;
	cout<<"2.删除表中指定的值"<<endl;
	cout<<"输入你的选择:"<<endl;
	cin>>choice;
	switch (choice)
	{
	case 1:
		int pos,i;
		cout<<"输入一个位置:"<<endl;
		cin>>pos;
		if (pos<1||pos>L.length)
		{
			cout<<"这个位置没有数据!"<<endl;
			return ERROR;
		}
		for (i = pos-1;i<L.length-1;i++)
		{
			L.elem[i] = L.elem[i+1];
		}
		L.length--;   //表中数据减一
		return OK;
		break;
	case 2:
		int value;
		cout<<"输入一个值:"<<endl;
		cin>>value;
		for (i = 0;i<L.length;i++)
		{
			if (value == L.elem[i])
			{
				pos = i;//记录下这个i值,我们只删除第一个匹配的
				break;
			}
		}
		for (i = pos;i<L.length-1;i++)//从pos位置开始,将后面的所有数据依次向前移动一位
		{
			L.elem[i] = L.elem[i+1];
		}
		L.length--;   //表中数据减一
		return OK;
		break;
	default:
		cout<<"没有这个选项"<<endl;
		return ERROR;
	}
}

颠倒顺序表:

颠倒的方式很多,但是我想这是比较简单的一种,还有一些其他的方式,例如再开辟一个数组,但这样很麻烦。

Status Reverse(SqList &L)
{
	if (L.length ==0) return ERROR;
	ElemType temp;
	int i;
	for (i = 0;i<(L.length)/2;i++)//直接将首尾数据交换,同时i++
	{
		temp = L.elem[i];
		L.elem[i] = L.elem[L.length-1-i];
		L.elem[L.length-1-i] = temp;
	}
	return OK;
}

排序函数:

这里只实现了升序排列,而且用的是效率一般的冒泡排序,大家可以试试快速排序。

Status Sort(SqList &L)
{
	if (L.length ==0) return ERROR;
	int i,j;
	ElemType temp,min;
	for(i = 0;i<L.length-1;i++)//冒泡排序
	{
		for (j = 0;j<L.length-i-1;j++)
		{
			if (L.elem[j]>L.elem[j+1])
			{
				temp = L.elem[j];
				L.elem[j] = L.elem[j+1];
				L.elem[j+1] = temp;
			}
		}
	}
	return OK;
}


插入数据:

根据题目要求,这里只实现了在有序表中的插入操作,而不是指定位置插入。建议大家也可以实践一下,

注意:所有的插入操作与删除操作都要注意对length的改变,还有就是当表满了的时候listsize也要变化。

Status Insert(SqList &L)
{
	ElemType value;
	int i = 0,pos;
	cout<<"提示:请确保出入之前顺序表有序,否则插入操作可能出错"<<endl;
	cout<<"输入要插入的数据"<<endl;
	cin>>value;
	if  (L.length>=L.listsize)//顺序表已满
	{
		ElemType *newbase;
		newbase = (ElemType*)realloc(L.elem,(INIT_SIZE+INCRE)*sizeof(ElemType));
		if (!newbase)
		{
			cout<<"重分配内存失败"<<endl;
			return ERROR;
		}
		L.elem = newbase;
		L.listsize = INIT_SIZE+INCRE;
	}
	while (value >= L.elem[i])
	{
		i++;
	}
	pos = i;
	for(i = L.length;i>=pos;i--)
	{
		L.elem[i+1] = L.elem[i]; 
	}
	L.elem[pos] = value;
	L.length++;
	return OK;
}



每天进步一点点


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!