数据结构——线性表的顺序表示

数据结构——线性表的顺序表示

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;
}

结果:
这里写图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值