目录
类型重定义,可以方便修改线性表中的数据元素的类型
typedef int ElemType; // 数据元素类型重定义
const int MAX_SIZE = 100; // 假设顺序表的最大容量为100
使用重定义的数据类型可以方便后期的修改,如果想要将数据类型更改一下,就不需要在海量代码中一个一个的修改,只需修改 typedef int ElemType; 这一行代码即可,后期维护更加便捷。
定义顺序表结构体
// 顺序表结构体
typedef struct {
ElemType* data; // 数组用于存储元素
int length; // 当前顺序表中有效元素的个数
int capacity; //记录当前顺序表的最大容量
} SeqList;
typedef是在C和C++编程语言中的一个关键字。作用是为现有的数据类型(int、float、char……)创建一个新的名字,目的是为了使代码方便阅读和理解。
data为定义的数组,可以用来储存元素。
length表示当前数组中含有的有效元素个数,初始状态为0。
capacity表示该数组中最大含有的元素个数,插入数据的个数不能超过这个值,否则将会插入失败。
操作1、初始化顺序表
// 初始化顺序表
bool initSeqList(SeqList &seqList) {
seqList.data = new ElemType[MAX_SIZE];
seqList.length = 0; // 将顺序表长度初始化为0,表示当前没有元素
seqList.capacity = MAX_SIZE; //capacity表示该数组中最大含有的元素个数
return true;
}
seqList.data = new ElemType[MAX_SIZE];
这段代码是为数组data申请一个长度为MAX_SIZE的空间,意思就是数组里面最多储存MAX_SIZE个元素,这个值由capacity记录。
seqList.length=0;
为seqList.length赋值,表示当前顺序表里面存在0个元素,这是初始化顺序表必不可少的一部分。
操作2、销毁顺序表
// 销毁顺序表
bool freeSeqList(SeqList& seqList) {
free(seqList.data);
seqList.data = NULL;
seqList.length = 0;
seqList.capacity = 0;
return true;
}
该操作与清空顺序表不同,销毁的顺序表空间已经被释放,不能再进行插入,删除等操作。
操作3、清空顺序表
// 清空顺序表
bool destroySeqList(SeqList& seqList) {
seqList.length = 0;
if(seqList.length == 0)
return true;
else
return false;
}
seqList.length = 0;
将seqList.length重新赋值为0,与初始化不一样的是,此时的数组中可能含有元素,但是length赋值为0以后,数组中的元素变为无效元素,虽然存在,但是都不会再用到。
操作4、判断线性表是否为空
//判断线性表是否为空
bool is_null(SeqList& seqList)
{
if(seqList.length == 0)
return true;
else
return false;
}
length中储存的便是数组的长度,如果seqList.length = 0,则为空。
否则不为空。
操作5、求线性表长度
//线性表长度
int length_seqList(SeqList& seqList)
{
return seqList.length;
}
注意:length中储存的便是数组的长度,直接输出seqList.length便是线性表的长度。
操作6、获取线性表中指定位置的元素
//查找指定位置的元素
ElemType find_addressSeqList(SeqList& seqList,int address)
{
address --;
if(address >= seqList.length || address <= 0)
return -1;
else
return seqList.data[address];
}
因为数组的位置是0~MAX_SIZE - 1,但是我们平时认为的位置是从1开始的,例如:1 2 3 999我们会认为第一个位置是1,第四个位置是999,但是在数组中1在第0个位置,999在第3个位置,所以要进行 address - - 操作。
如果address >= seqList.length || address <= 0则说明这个位置没有元素,返回-1,否则返回这个位置的元素值。
操作7、获取线性表元素的位置
//查找指定元素的位置
int findSeqList(SeqList& seqList,ElemType element)
{
for(int i = 0; i < seqList.length; i ++)
{
if(seqList.data[i] == element)
return ++ i;
}
return -1;
}
需要从零开始在数组中查找元素位置,如果找到与要查找元素值相等的元素,就返回该位置(需要加1,原因与操作6相同),否则就返回-1。
操作8、求前驱
//前驱
ElemType before(SeqList& seqList,ElemType num)
{
for(int i = 1; i < seqList.length;i ++)
{
if(num == seqList.data[i])
return seqList.data[i - 1];
}
return -1;
}
求前驱是指,输入一个元素值(而不是位置),求该元素在顺序表中的直接前驱元素值。
我们可以依次在数组中查找,找到该元素后输出它前面的一个元素,需要注意的是:如果数组中不存在该元素,或者该元素在数组的第一位,是不存在前驱的。
操作9、求后继
//后继
ElemType after(SeqList& seqList,ElemType num)
{
for(int i = 0; i < seqList.length - 1;i ++)
{
if(num == seqList.data[i])
return seqList.data[i + 1];
}
return -1;
}
求后继是指:输入一个元素值(而不是位置),求该元素在顺序表中的直接后继元素值;
我们可以依次在数组中查找,找到该元素后输出它后面的一个元素,需要注意的是:如果数组中不存在该元素,或者该元素在数组的最后一位,是不存在后继的。
操作10、在顺序表指定位置插入元素
// 在顺序表中插入元素
bool insert(SeqList& seqList, ElemType element, int address) {
address --;
if (seqList.length >= seqList.capacity) {
cout << "顺序表已满,无法插入元素!" << endl;
return false;
}else if (address > seqList.length || address < 0) {
cout << "不能在这个位置插入元素!" << endl;
return false;
}
for (int i = seqList.length - 1; i >= address; i--) {
seqList.data[i + 1] = seqList.data[i];
}
seqList.data[address] = element;
seqList.length++;
return true;
}
在插入元素的时候,插入的位置可以在顺序表的前一位或者后一位,这种插入是允许的,但是不能在小于1的位置插入数据,也不能在l.length+2以及更加靠后的位置插入元素,也可以在顺序表中间的位置插入元素,插入元素之前需要将该位置以及该位置之后的元素全体向后移动一位,需要警惕值覆盖,需要先从最后一位向后移,防止元素被覆盖。
操作11、删除线性表指定位置的元素
// 删除指定位置的元素
bool deleteElement(SeqList& seqList, int position) {
if (position < 1 || position > seqList.length) {
// 位置越界
return false;
} else {
for (int i = position-1; i < seqList.length - 1; i++) {
seqList.data[i] = seqList.data[i+1];
}
seqList.length--;
return true;
}
}
在删除元素的时候,删除的位置只能在1~length之间,这种删除是允许的,但是不能在小于1的位置删除数据,也不能在l.length+1及更加靠后的位置删除元素,插入元素之前需要将该位置以及该位置之后的元素全体向前移动一位,需要警惕值覆盖,需要先从position的后一位开始将元素向前移动,防止元素被覆盖。
操作12、显示线性表
//显示顺序表
void show(SeqList& seqList)
{
for (int i = 0; i < seqList.length; i++) {
cout << seqList.data[i] << " ";
}
cout << endl;
}
从0开始一直到seqList - 1,依次遍历输出数组中的元素即可。
操作13、合并两个非递减有序的线性表(去重)
void solve13()
{
SeqList l1,l2,l3;
initSeqList(l1);
initSeqList(l2);
initSeqList(l3);
insert(l1, 5, 1);
insert(l1, 4, 1);
insert(l1, 3, 1);
insert(l1, 3, 1);
insert(l1, 2, 1);
insert(l2, 7, 1);
insert(l2, 6, 1);
insert(l2, 6, 1);
insert(l2, 5, 1);
insert(l2, 4, 1);
insert(l2, 1, 1);
cout << "第一个线性表中的元素是(2,3,3,4,5)" << endl;
cout << "第二个线性表中的内容是(1,4,5,6,6,7)" << endl;
cout << "合并后的结果:" << endl;
for(int i = 1; i < l1.length; i ++)
{
if(l1.data[i] == l1.data[i - 1])
{
deleteElement(l1, i);
}
}
for(int i = 1; i < l2.length; i ++)
{
if(l2.data[i] == l2.data[i - 1])
{
deleteElement(l2, i);
}
}
int flag1 = 0,flag2 = 0,flag3 = 0;
for(;;)
{
if(flag1 >= l1.length || flag2 >= l2.length) break;
if(l1.data[flag1] > l2.data[flag2])
{
insert(l3, l2.data[flag2 ++], ++ flag3);
}else if(l1.data[flag1] < l2.data[flag2]){
insert(l3, l1.data[flag1 ++], ++ flag3);
}else{
insert(l3, l1.data[flag1 ++], ++ flag3);
flag2 ++;
}
}
for(;flag1 < l1.length;)
{
insert(l3, l1.data[flag1 ++], ++ flag3);
}
for(;flag2 < l2.length;)
{
insert(l3, l2.data[flag2 ++], ++ flag3);
}
show(l3);
}
先将元素一次插入l1,l2中,再对l1,l2中的元素进行去重,最后利用归并排序(去重)将l1,l2中的元素添加到l3中,最后再将l3输出即可。
目录
完整代码
#include<iostream>
using namespace std;
typedef int ElemType; // 数据元素类型重定义
const int MAX_SIZE = 100; // 假设顺序表的最大容量为100
// 顺序表结构体
typedef struct {
ElemType* data; // 数组用于存储元素
int length; // 当前顺序表中有效元素的个数
int capacity; //记录当前顺序表的最大容量
} SeqList;
// 初始化顺序表
bool initSeqList(SeqList &seqList) {
seqList.data = new ElemType[MAX_SIZE];
seqList.length = 0; // 将顺序表长度初始化为0,表示当前没有元素
seqList.capacity = MAX_SIZE;
return true;
}
// 清空顺序表
bool destroySeqList(SeqList& seqList) {
seqList.length = 0;
if(seqList.length == 0)
return true;
else
return false;
}
// 销毁顺序表
bool freeSeqList(SeqList& seqList) {
free(seqList.data);
seqList.data = NULL;
seqList.length = 0;
seqList.capacity = 0;
return true;
}
// 在顺序表中插入元素
bool insert(SeqList& seqList, ElemType element, int address) {
address --;
if (seqList.length >= seqList.capacity) {
cout << "顺序表已满,无法插入元素!" << endl;
return false;
}else if (address > seqList.length || address < 0) {
cout << "不能在这个位置插入元素!" << endl;
return false;
}
for (int i = seqList.length - 1; i >= address; i--) {
seqList.data[i + 1] = seqList.data[i];
}
seqList.data[address] = element;
seqList.length++;
return true;
}
//查找指定元素的位置
int findSeqList(SeqList& seqList,ElemType element)
{
for(int i = 0; i < seqList.length; i ++)
{
if(seqList.data[i] == element)
return ++ i;
}
return -1;
}
//查找指定位置的元素
ElemType find_addressSeqList(SeqList& seqList,int address)
{
address --;
if(address >= seqList.length)
return -1;
else
return seqList.data[address];
}
//显示顺序表
void show(SeqList& seqList)
{
for (int i = 0; i < seqList.length; i++) {
cout << seqList.data[i] << " ";
}
cout << endl;
}
//前驱
ElemType before(SeqList& seqList,ElemType num)
{
for(int i = 1; i < seqList.length;i ++)
{
if(num == seqList.data[i])
return seqList.data[i - 1];
}
return -1;
}
//后继
ElemType after(SeqList& seqList,ElemType num)
{
for(int i = 0; i < seqList.length - 1;i ++)
{
if(num == seqList.data[i])
return seqList.data[i + 1];
}
return -1;
}
// 删除指定位置的元素
bool deleteElement(SeqList& seqList, int position) {
if (position < 1 || position > seqList.length) {
// 位置越界
return false;
} else {
for (int i = position-1; i < seqList.length - 1; i++) {
seqList.data[i] = seqList.data[i+1];
}
seqList.length--;
return true;
}
}
void solve13()
{
SeqList l1,l2,l3;
initSeqList(l1);
initSeqList(l2);
initSeqList(l3);
insert(l1, 5, 1);
insert(l1, 4, 1);
insert(l1, 3, 1);
insert(l1, 3, 1);
insert(l1, 2, 1);
insert(l2, 7, 1);
insert(l2, 6, 1);
insert(l2, 6, 1);
insert(l2, 5, 1);
insert(l2, 4, 1);
insert(l2, 1, 1);
cout << "第一个线性表中的元素是(2,3,3,4,5)" << endl;
cout << "第二个线性表中的内容是(1,4,5,6,6,7)" << endl;
cout << "合并后的结果:" << endl;
for(int i = 1; i < l1.length; i ++)
{
if(l1.data[i] == l1.data[i - 1])
{
deleteElement(l1, i);
}
}
for(int i = 1; i < l2.length; i ++)
{
if(l2.data[i] == l2.data[i - 1])
{
deleteElement(l2, i);
}
}
int flag1 = 0,flag2 = 0,flag3 = 0;
for(;;)
{
if(flag1 >= l1.length || flag2 >= l2.length) break;
if(l1.data[flag1] > l2.data[flag2])
{
insert(l3, l2.data[flag2 ++], ++ flag3);
}else if(l1.data[flag1] < l2.data[flag2]){
insert(l3, l1.data[flag1 ++], ++ flag3);
}else{
insert(l3, l1.data[flag1 ++], ++ flag3);
flag2 ++;
}
}
for(;flag1 < l1.length;)
{
insert(l3, l1.data[flag1 ++], ++ flag3);
}
for(;flag2 < l2.length;)
{
insert(l3, l2.data[flag2 ++], ++ flag3);
}
show(l3);
}
void line()
{
cout << "---------------------------" << endl;
}
void menu()
{
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 << "退出,请输入一个负数!" << endl;
}
int main()
{
menu();
SeqList mySeqList;
int op;
while(1)
{
line();
cout << "请输入你的选择:";
cin >> op;
if(op == 1){
//1----初始化一个线性表
if(initSeqList(mySeqList))
cout << "顺序表初始化成功!" << endl;
else
cout << "初始化失败!" << endl;
}else if(op == 2){
//2----销毁线性表
if(freeSeqList(mySeqList))
cout << "销毁成功!" << endl;
else
cout << "销毁失败!" << endl;
}else if(op == 3){
//3----清空线性表
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
if(destroySeqList(mySeqList))
cout << "清空成功!" << endl;
else cout << "清空失败!" << endl;
}else if(op == 4){
//4----判断线性表是否为空
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
if(mySeqList.length == 0)
cout << "线性表为空!" << endl;
else
cout << "线性表不为空!" << endl;
}else if(op == 5){
//5----求线性表长度
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
cout << "线性表的长度为:" << mySeqList.length << endl;
}else if(op == 6){
//6----获取线性表中指定位置的元素
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
int address;
cout << "输入要查找的位置:";
cin >> address;
ElemType i = find_addressSeqList(mySeqList,address);
if(i == -1) cout << "查找失败!" << endl;
else cout << "查找成功:" << i << endl;
}else if(op == 7){
//7----获取线性表元素的位置
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
ElemType num;
cout << "请输入想要获取位置的元素值:";
cin >> num;
int i = findSeqList(mySeqList,num);
if(i == -1) cout << "该元素不存在!" << endl;
else cout << "该元素位置在:" << i << endl;
}else if(op == 8){
//8----求前驱
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
ElemType num;
cout << "请输入元素:";
cin >> num;
ElemType i = before(mySeqList,num);
if(i == -1) cout << "没有前驱!" << endl;
else cout << "前驱是:" << i << endl;
}else if(op == 9){
//9----求后继
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
ElemType num;
cout << "请输入元素:";
cin >> num;
ElemType i = after(mySeqList,num);
if(i == -1) cout << "没有后继!" << endl;
else cout << "后继是:" << i << endl;
}else if(op == 10){
//10----在线性表指定位置插入元素
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
int n;
cout << "请输入要插入的元素个数:";
cin >> n;
for (int i = 0; i < n; i++) {
ElemType element;
cout << "请输入第" << i + 1 << "个元素:";
cin >> element;
int position;
cout << "请输入要插入的位置:";
cin >> position;
if(insert(mySeqList, element,position))
{
cout << "插入成功!" << endl;
}
}
}else if(op == 11){
//11----删除线性表指定位置的元素
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
int address;
cout << "请输入要删除的位置:" << endl;
cin >> address;
if(deleteElement(mySeqList, address))
cout << "删除成功!" << endl;
else
cout << "删除失败!" << endl;
}else if(op == 12){
//12----显示线性表
if(mySeqList.capacity == 0)
{
cout << "线性表已被销毁!" << endl;
continue;
}
show(mySeqList);
}else if(op == 13){
//13----合并两个非递减有序的线性表
solve13();
}else if(op <= 0){
//退出,请输入一个负数!
break;
}
}
cout << "程序已经结束!" << endl;
}