数据结构——线性表的顺序表示
1年前学了数据结构,到现在发现有很多东西已经忘记了,趁这要帮学弟学妹们辅导的机会,重新复习一下数据结构的一些知识。本文是我学习的笔记,如果有错误的地方,欢迎指正。
本文记录的主要的内容是线性表顺序表示的相关内容,涉及顺序表的创建,初始化,在指定位置插入元素,删除指定位置元素,读取指定位置元素,顺序表元素遍历输出,还有最后实现了课本第二章例2-2中的顺序表的合并。(所用的课本是清华大学出版社,严蔚敏教授等所著的《数据结构(c语言版)》)
本文中,使用一个固定大小的数组存储数据元素。事实上线性表的长度是可变的,且所需的最大存储空间随问题不同而不同,则需要使用动态分配的数组
1)顺序表结构定义
typedef int ElemType;
typedef struct {
ElemType e[MAX];//存储数据
int length;//数据个数
}sqList;
2)初始化
//线性表初始化
Status InitList(sqList &L)
{
L.length = 0;
return OK;
}
这里需要说明一下,Status 其实是一个变量类型,也就是int,他是函数的返回状态,如:当函数执行成功是返回OK,也就是1,当失败返回ERROR,是0。Status其实就是int的替身。本文中代码体现在:
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAX 100
*typedef int Status;*
3) 插入元素
这里插入元素是指向某一个顺序表中的某一个位置插入一个元素。
这里有一个顺序表,目前长度为4,位置1的元素为数字1,位置2的元素为数字2….
我现在要在位置2(数组的下标为1)插入一个元素5,现在,位置2被元素2占着,如果要插入数字5,必需要将位置2腾出来,也就是位置2以及之后的所有元素都要向右移一格。如下图,
这个时候就可以把数字5插入。
此时的长度为5。
//在线性表指定位置插入数据
Status InsertList(sqList &L, int i,ElemType e)
{
int j;
if (i<1 || i>L.length + 1) return ERROR;//如果想将结点插入不该插入的位置
if (L.length == MAX) return ERROR;//如果表已满,没有位置插入节点
if (i <= L.length)//如果插入不在表尾
{
for (j = L.length; j > i-1; j--)//将插入位置的元素及之后的元素右移
{
L.e[j] = L.e[j - 1];
}
}
L.e[i-1] = e;
L.length++;
return OK;
}
4)删除元素
删除和插入类似,只是一个是左移元素,一个是右移元素
Status DeleteList(sqList &L, int i, ElemType &e)
{
if (i<1 || i>L.length) return ERROR;
e = L.e[i - 1];//保存将要删除元素的值
for (int j = i; j < L.length; j++)//将被删除元素之后的元素左移
{
L.e[j - 1] = L.e[j];
}
L.length--;
return OK;
}
5) 读取元素
Status GetElem(sqList L,int i, ElemType &e)
{
if (i < 1 || i > L.length+1||L.length==0)
return ERROR;
e = L.e[i - 1];
return OK;
}
6 )遍历
Status Show(sqList L)
{
if (L.length == 0)
cout << "空表";
for (int i = 0; i < L.length; i++)
cout << L.e[i]<<" ";
cout << endl;
return OK;
}
7.)顺序表的合并
void MergeList(sqList La, sqList Lb, sqList &Lc)
{
int lalen = La.length;//获取线性表的长度,即现有元素个数
int lblen = Lb.length;
int i=1,j=1, k=0;
int ea, eb;
while (i <= lalen&&j <= lblen)
{
GetElem(La, i, ea);
GetElem(Lb, j, eb);
if (ea <eb) //如果La中第i个元素大小小于Lb中第j个元素大小
{
InsertList(Lc, ++k, ea);//将ea插入到Lc中
++i;
}
else
{
InsertList(Lc, ++k, eb);//否则将eb插入Lc中
++j;
}
}
while (i <= lalen)//当Lb中的元素已经全部插入到Lc中,而La中还有元素未插入Lc中
//即La中现在剩下的元素比Lb中的所有元素都大
{
GetElem(La, i++, ea);
InsertList(Lc, ++k, ea);
}
while (j <= lblen)//同上
{
GetElem(Lb, j++, eb);
InsertList(Lc, ++k, eb);
}
}
全部代码如下:
#include "iostream"
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAX 100
typedef int Status;
typedef int ElemType;
//不会自动分配存储空间
typedef struct {
ElemType e[MAX];//存储数据
int length;//数据个数
}sqList;
//线性表初始化
Status InitList(sqList &L)
{
L.length = 0;
return OK;
}
//获取指定位置的元素
Status GetElem(sqList L,int i, ElemType &e)
{
if (i < 1 || i > L.length+1||L.length==0)
return ERROR;
e = L.e[i - 1];
return OK;
}
//在线性表指定位置插入数据
Status InsertList(sqList &L, int i,ElemType e)
{
int j;
if (i<1 || i>L.length + 1) return ERROR;//如果想将结点插入不该插入的位置
if (L.length == MAX) return ERROR;//如果表已满,没有位置插入节点
if (i <= L.length)//如果插入不在表尾
{
for (j = L.length; j > i-1; j--)//将插入位置的元素及之后的元素右移
{
L.e[j] = L.e[j - 1];
}
}
L.e[i-1] = e;
L.length++;
return OK;
}
//删除线性表中指定位置的数据
Status DeleteList(sqList &L, int i, ElemType &e)
{
if (i<1 || i>L.length) return ERROR;
e = L.e[i - 1];//保存将要删除元素的值
for (int j = i; j < L.length; j++)//将被删除元素之后的元素左移
{
L.e[j - 1] = L.e[j];
}
L.length--;
return OK;
}
//输出线性表中所有的数据
Status Show(sqList L)
{
if (L.length == 0)
cout << "空表";
for (int i = 0; i < L.length; i++)
cout << L.e[i]<<" ";
cout << endl;
return OK;
}
//清空线性表
Status ClearList(sqList &L)
{
L.length = 0;
return OK;
}
//顺序表的合并。
void MergeList(sqList La, sqList Lb, sqList &Lc)
{
int lalen = La.length;//获取线性表的长度,即现有元素个数
int lblen = Lb.length;
int i=1,j=1, k=0;
int ea, eb;
while (i <= lalen&&j <= lblen)
{
GetElem(La, i, ea);
GetElem(Lb, j, eb);
if (ea <eb) //如果La中第i个元素大小小于Lb中第j个元素大小
{
InsertList(Lc, ++k, ea);//将ea插入到Lc中
++i;
}
else
{
InsertList(Lc, ++k, eb);//否则将eb插入Lc中
++j;
}
}
while (i <= lalen)//当Lb中的元素已经全部插入到Lc中,而La中还有元素未插入Lc中
//即La中现在剩下的元素比Lb中的所有元素都大
{
GetElem(La, i++, ea);
InsertList(Lc, ++k, ea);
}
while (j <= lblen)//同上
{
GetElem(Lb, j++, eb);
InsertList(Lc, ++k, eb);
}
}
//测试代码
void Test()
{
sqList L;
int e;
InitList(L);//初始化线性表
InsertList(L, 1, 1);//插入元素1
InsertList(L, 2, 2);//插入元素2
InsertList(L, 3, 3);
InsertList(L, 4, 4);
cout << "L中的元素有:";
Show(L);//输出线性表中所有的数据
GetElem(L, 3, e);
cout << "删除的元素值为:"<<e << endl;
DeleteList(L, 3, e);//删除线性表中第三个元素
cout << "删除后,L中的元素为:";
Show(L);//输出删除操作后的线性表
ClearList(L);//清空线性表中的元素
cout << "清空线性表后,L中的元素有:";
Show(L);
}
//顺序表合并的测试函数
void TestMergeList()
{
sqList La, Lb, Lc;
InitList(La);
InitList(Lb);
InitList(Lc);
//给La插入数字1,3,5,7
//给Lb插入数字2,4,6,8
for (int i = 1; i <= 4; i++)
{
InsertList(La, i, 2 * i-1);
InsertList(Lb, i, 2 * i);
}
MergeList(La, Lb, Lc);
cout << "合并前的顺序表为:" << endl;
cout << "La ";
Show(La);
cout << "Lb ";
Show(Lb);
cout << "合并后的顺序表为:";
Show(Lc);
}
int main()
{
Test();
TestMergeList();
getchar();
return 0;
}
结果: