本次给大家带来顺序表的基本操作的相关操作,与大家交流学习,希望对大家有所帮助,不足之处也请大家多多留言探讨。最后,码字不易,喜欢的话点点关注哦!🥰🥰🥰
前言
为了方便操作,代码中使用了C++中的引用变量相关知识,不了解的小伙伴们可提前了解一下相关知识。即使不懂原理,也没有关系,只拿来进行简单的操作还是比较容易的哈。当然,用指针也是可以的,大家可以了解完算法后,用自己习惯的操作再实现一遍,效果会更好哦。
核心算法
插入
//插入操作(在第i个元素之前插入值为x的元素)
void ListInsert(SqList& L, ElemType x, int i) {
//判断插入位置是否合法(1<=i<=L.length+1)
if (i<1 || i>L.length+1) {
printf("插入位置不合法!\n");
return;
}
if (L.length >= L.listsize) {
ElemType* newbase = (ElemType*)realloc(L.elem, sizeof(SqList) * (L.listsize*2));
if (!newbase) {
printf("分配空间失败!\n");
exit(-1);
}
L.elem = newbase;
L.listsize *= 2;
}
ElemType* p = &(L.elem[i-1]);//指向待插入元素位置
ElemType* q;//始终指向待移动的元素位置
for(q = &(L.elem[L.length - 1]);q>=p;q--){
*(q+1) = *q;
}
*p = x;
L.length++;
}
我的疑惑:该算法是在第i个元素之前插入元素,我们知道L.length就是元素的个数,也就是说只能在第一个元素之前到最后一个元素之前进行插入(1≤i≤L.length)。但是看了书上和一些其他博主的博客发现在判断插入位置是否合法的代码上,都采用了1≤i≤L.length+1(本次博客源码中所采用的形式),可以看到,这样的话多了一个插入位置,也就是最后一个元素的后面。但是该算法的目的明明是在第i个元素前插入,这样的话不就变成在第i个位置上插入元素显然与算法要求向悖。
期待聪明的你来解答哦!
期待聪明的你来解答哦!
期待聪明的你来解答哦!
删除
//删除操作(删除第i个元素,并用e返回其值)
void ListDelete(SqList& L, int i, ElemType& e) {
if (i<1 || i>L.length) {
printf("删除位置不合法!\n");
return;
}
ElemType* p = &(L.elem[i - 1]);//先保存待删元素位置
e = *p;
ElemType* q=&(L.elem[L.length-1]);//指向最后一个元素
for (++p; p <= q; p++) { //p始终指向待移动元素
*(p-1) = *p;
}
L.length--;
}
查找
//查找操作(查找首个值为e的元素,并返回它的位序号)
int LocateElem(SqList L, ElemType e) {
int i;
for (i = 1; i <= L.length && L.elem[i - 1] != e; i++) {
;
}
if (i <= L.length) {
return i;
}
else {
return 0;
}
}
输出
//输出操作
void DisplayList(SqList L) {
for (int i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}
printf("\n");
}
逆置
//逆置操作
void ReverseSqList(SqList& L) {
for (int i = 0; i < L.length / 2; i++) {
ElemType t = L.elem[i];
L.elem[i] = L.elem[L.length - 1 - i];
L.elem[L.length - 1-i] = t;
}
}
删除有序表中的重复元素
//删除有序顺序表中所有的重复元素
void DeDuplicates(SqList& L) {
for (int i = 0; i < L.length - 1; ) {
if (L.elem[i]==L.elem[i+1]) {
for (int p = i + 1; p < L.length; p++) {
L.elem[p - 1] = L.elem[p];
}
L.length--;
}
else {
i++;
}
}
}
有序表的插入
//在有序顺序表中插入一个元素仍保持有序(从小到大)
void ListInsert_SOT(SqList& L,int x) {
int i;
if (L.length >= L.listsize) {
ElemType* newbase = (ElemType*)realloc(L.elem,sizeof(SqList)*(L.listsize*2));
if (!newbase) {
printf("分配空间失败!\n");
exit(-1);
}
L.elem = newbase;
L.listsize *= 2;
}
for (i = L.length-1; i>=0&&x<L.elem[i]; i--) {
L.elem[i+1] = L.elem[i];//边比较边后移
}
L.elem[i+1] = x;
L.length++;
}
合并
//合并操作(将两个非递减有序表合并为一个新的有序表)
void MergeList(SqList La,SqList Lb,SqList& Lc) {
//先将La中的元素全放到Lc中
for (int i = 0; i<La.length; i++) {
ListInsert(Lc,La.elem[i],i+1);
}
//再将Lb中的元素与Lc中元素比较后插入Lc中
for (int j = 0; j < Lb.length; j++) {
ListInsert_SOT(Lc,Lb.elem[j]);
}
}
源码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100 //为顺序表分配空间的容量
typedef int ElemType;
typedef struct {
ElemType* elem;//顺序表的基地址
int length;//顺序表的当前长度
int listsize;//顺序表的当前容量
}SqList;
//初始化操作
void InitList(SqList& L) {
L.elem = (ElemType*)malloc(sizeof(SqList) * MAXSIZE);
if (!L.elem) {
printf("分配空间失败!\n");
exit(-1);
}
L.length = 0;
L.listsize = MAXSIZE;
}
//判空操作
int ListEmpty(SqList L){
if (L.length == 0) {
return 1;
}
else {
return 0;
}
}
//求顺序表的长度
int ListLength(SqList L) {
return L.length;
}
//插入操作(在第i个元素之前插入值为x的元素)
void ListInsert(SqList& L, ElemType x, int i) {
//判断插入位置是否合法(1<=i<=L.length+1)
if (i<1 || i>L.length+1) {
printf("插入位置不合法!\n");
return;
}
if (L.length >= L.listsize) {
ElemType* newbase = (ElemType*)realloc(L.elem, sizeof(SqList) * (L.listsize*2));
if (!newbase) {
printf("分配空间失败!\n");
exit(-1);
}
L.elem = newbase;
L.listsize *= 2;
}
ElemType* p = &(L.elem[i-1]);//指向待插入元素位置
ElemType* q;//始终指向待移动的元素位置
for(q = &(L.elem[L.length - 1]);q>=p;q--){
*(q+1) = *q;
}
*p = x;
L.length++;
}
//删除操作(删除第i个元素,并用e返回其值)
void ListDelete(SqList& L, int i, ElemType& e) {
if (i<1 || i>L.length) {
printf("删除位置不合法!\n");
return;
}
ElemType* p = &(L.elem[i - 1]);//先保存待删元素位置
e = *p;
ElemType* q=&(L.elem[L.length-1]);//指向最后一个元素
for (++p; p <= q; p++) { //p始终指向待移动元素
*(p-1) = *p;
}
L.length--;
}
//查找操作(查找首个值为e的元素,并返回它的位序号)
int LocateElem(SqList L, ElemType e) {
int i;
for (i = 1; i <= L.length && L.elem[i - 1] != e; i++) {
;
}
if (i <= L.length) {
return i;
}
else {
return 0;
}
}
//输出操作
void DisplayList(SqList L) {
for (int i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}
printf("\n");
}
//逆置操作
void ReverseSqList(SqList& L) {
for (int i = 0; i < L.length / 2; i++) {
ElemType t = L.elem[i];
L.elem[i] = L.elem[L.length - 1 - i];
L.elem[L.length - 1-i] = t;
}
}
//***********************************************
//删除有序顺序表中所有的重复元素
void DeDuplicates(SqList& L) {
for (int i = 0; i < L.length - 1; ) {
if (L.elem[i]==L.elem[i+1]) {
for (int p = i + 1; p < L.length; p++) {
L.elem[p - 1] = L.elem[p];
}
L.length--;
}
else {
i++;
}
}
}
//在有序顺序表中插入一个元素仍保持有序(从小到大)
void ListInsert_SOT(SqList& L,int x) {
int i;
if (L.length >= L.listsize) {
ElemType* newbase = (ElemType*)realloc(L.elem,sizeof(SqList)*(L.listsize*2));
if (!newbase) {
printf("分配空间失败!\n");
exit(-1);
}
L.elem = newbase;
L.listsize *= 2;
}
for (i = L.length-1; i>=0&&x<L.elem[i]; i--) {
L.elem[i+1] = L.elem[i];//边比较边后移
}
L.elem[i+1] = x;
L.length++;
}
//合并操作(将两个非递减有序表合并为一个新的有序表)
void MergeList(SqList La,SqList Lb,SqList& Lc) {
//先将La中的元素全放到Lc中
for (int i = 0; i<La.length; i++) {
ListInsert(Lc,La.elem[i],i+1);
}
//再将Lb中的元素与Lc中元素比较后插入Lc中
for (int j = 0; j < Lb.length; j++) {
ListInsert_SOT(Lc,Lb.elem[j]);
}
}
int main()
{
ElemType x,e;
int i=0;
int m = 0, n = 0;
SqList L;
InitList(L);
printf("请输入顺序表中各元素的值:\n");
for (int j = 0; j < 6;j++) {
scanf("%d", &x);
ListInsert(L, x, j+1);
}
printf("该顺序表的长度为:%d\n", ListLength(L));
DisplayList(L);
printf("请分别输入要插入元素的值和位序号:\n");
scanf("%d %d", &x,&i);
ListInsert(L,x,i);
DisplayList(L);
printf("请输入您要删除元素的位序号:\n");
scanf("%d", &i);
ListDelete(L,i,e);
printf("删除后:\n");
DisplayList(L);
printf("被删除的元素为:%d\n", e);
printf("请输入要查找的元素:\n");
scanf("%d", &e);
printf("%d的位序号为:%d\n", e, LocateElem(L,e));
printf("*********************\n");
SqList L1;
InitList(L1);
printf("请输入有序顺序表中各元素的值:\n");
for (int j = 0; j < 6; j++) {
scanf("%d", &x);
ListInsert(L1, x, j + 1);
}
DeDuplicates(L1);
DisplayList(L1);
printf("请输入要插入的元素的值:");
scanf("%d",&x);
ListInsert_SOT(L1, x);
DisplayList(L1);
ReverseSqList(L1);
printf("逆置后:\n");
DisplayList(L1);
printf("************************\n");
SqList La, Lb, Lc;
InitList(La);
InitList(Lb);
InitList(Lc);
printf("请输入La的各元素值:");
for (int i = 0; i < 4; i++) {
scanf("%d", &x);
ListInsert(La, x,i+1);
}
printf("请输入Lb的各元素值:");
for (int i = 0; i < 6; i++) {
scanf("%d", &x);
ListInsert(Lb, x, i + 1);
}
MergeList(La, Lb, Lc);
printf("合并后:");
DisplayList(Lc);
return 0;
}
代码对不对,跑起来才知道,附运行截图:
![](https://img-blog.csdnimg.cn/img_convert/e43d30d733502ceb342ab2c6c2b29ff7.png)