今天和大家分享一下顺序表的基本操作
编写一个完整的程序,实现顺序表的建立、插入、删除、输出等基本运算。
(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;
}每天进步一点点
来源:CSDN
作者:灰色世界的阿信
链接:https://blog.csdn.net/he_and/article/details/78283756