Wangdao postgraduate entrance examination data structure--1. Sequence table

Table of contents

1 Introduction

2. Difficulties

2.1 C language does not have bool data type

2.2 The bit order of the sequence table starts from 1, while the bit order of the array starts from 0

2.3 The symbol & in the function means to take the address and return

3. Source code (static storage)

4. Dynamic storage

4.1 Structure writing

4.2 Initialization

4.3 The dynamic table can increase the table length

4.4 Source code (static + dynamic storage)


1 Introduction

Date: 2023.6.20

Book: 2024 Data Structure PubMed Review Guide (Wang Dao PubMed Series)

Content: Static storage implements the sequence table, and its basic operations, initialization, addition, deletion, search, empty judgment and traversal output.

InitList(SqList *L);//初始化

Length(SqList *L);//求表长

ListInsert(SqList *L,int i,Elemtype e);//插入操作

ListDelete(SqList *L,int i,Elemtype e);//删除操作

LocateElem(SqList *L,Elemtype e);//按值查找

GetElem(SqList *L,int i);//按位查找

OutputList(SqList L);//输出操作

2. Difficulties

There are many languages ​​to learn, and some grammar knowledge will be confused. There are some things that C language does not have , so you must pay attention! !

2.1 C language does not have bool data type

It’s a commonplace, C language doesn’t directly define bool type, but we can macro define one by ourselves.

#define bool char
#define false 0
#define true 1

2.2 The bit order of the sequence table starts from 1, while the bit order of the array starts from 0

The i-th position in the sequence table is expressed as L->data[i-1]. I have already marked what each i in the final code means. Let’s look at the source code in a while.


2.3 The symbol & in the function means to take the address and return

The symbol "&" means a reference call in C++. In C language, pointers can be used to achieve the same effect, for example:

SqList &L  ==   SqList l; SqList *L=&l;


3. Source code (static storage)

#include <stdio.h>
#include <stdlib.h>

//c语言宏定义bool操作
#define bool char 
#define true 1
#define false 0

//顺序表及数组长度
#define MaxSize 10

//数据元素数据类型
typedef int ElemType;

//顺序表结构定义
typedef struct {
    ElemType data[MaxSize];//顺序表元素
    int length;//顺序表长度
    /* data */
}SqList;

//基本操作1.初始化一个顺序表

void InitList(SqList *L){

    for(int i=0;i<MaxSize;i++){
        L->data[i]=0;
    
    L->length=0;
    }
}

//基本操作2.插入一个数据元素
/*
    在顺序表L的第i(1<=i<=L.length+1)个位置插入新元素e
    若输入的i不合法,则返回false,表示插入失败
    否则,将顺序表的第i个元素及其后的所有元素右移一个位置,
    腾出一个空位置插入新元素e,
    顺序表长度增加1,插入成功,返回true
*/
bool ListInsert(SqList *L,int i,ElemType e){
    if(i<1||i>L->length+1) return false; //i
    if(L->length>=MaxSize) return false;
    for(int j=L->length;j>=i;j--){
        L->data[j]=L->data[j-1];
    }//将i位置后面的元素从最后面向右推1
    L->data[i-1]=e;
    L->length++;
    printf("当前表长是:%d\n",L->length);
    return true;
}//后退从后开始

//基本操作3.删除操作
/*
删除i位置的元素,并且用e返回其值
*/
bool ListDelete(SqList *L,int i,ElemType *e){
    if(i<1||i>L->length) return false;
    *e=L->data[i-1];
    for(int j=i;j<L->length;j++){
        L->data[j-1]=L->data[j];
    }
    L->length--;
    return true;
}//前推从前面开始

//基本操作4.1.按位查找

bool GetElem(SqList *L,int i){
    if(i<1||i>L->length){
        printf("查找失败\n");
        return false;
    }
    printf("顺序表第%d个元素是%d\n",i,L->data[i-1]);
}

//基本操作4.2.按值查找(顺序查找)

int LocateElem(SqList *L,ElemType e){
    for(int i=0;i<L->length;i++){
        if(L->data[i]==e){
            printf("查找元素%d位于第%d个\n",e,i+1);
            return i+1;
        }
        
    }
    return 0;
}

//基本操作5.遍历输出顺序表
bool OutputList(SqList *L){
    //判空操作
    if(L->length==0){
        printf("顺序表是空的。\n");
        return false;
    }
    int i=1;
    while (i<L->length){
        printf("顺序表的第%d个元素是%d.\n",i,L->data[i-1]);
        i++;
    }
    return true;
}

void text1(){
    printf("********************************************************\n");
    printf("**           欢迎使用本数据表,请选择您的操作            **\n");
    printf("**   1.插入新元素                                      **\n");
    printf("**   2.插入元素                                        **\n");
    printf("**   3.删除元素                                        **\n");
    printf("**   4.输出顺序表                                      **\n");
    printf("**   5.按位查找                                        **\n");
    printf("**   6.按值查找                                        **\n");
    printf("**   7.输出表长                                        **\n");
    printf("**   0.退出程序                                        **\n");
    printf("********************************************************\n");

}

void text2(SqList *L){
    int a;
    while(1){
    text1();
    scanf("%d",&a);
    switch (a){
    case 0:
        exit(0);
        break;
    case 1:{
        int x;
        printf("请输入你要插入的值(默认插入顺序表最后一位):\n");
        scanf("%d",&x);
        bool b = ListInsert(L,L->length+1,x);
        if(b)   printf("插入成功!\n");
        else    printf("插入失败!\n");
        break;
    }
    case 2:{
        int x,y;
        printf("请输入您要插入的值:\n");
        scanf("%d",&x);
        printf("请输入您要插入的位置:\n");
        scanf("%d",&y);
        bool b = ListInsert(L,y,x);
        if(b)   printf("插入成功!\n");
        else    printf("插入失败!\n");
        break ;
    }
    case 3:{
        int x,y;
        printf("请输入您要删除的值:\n");
        scanf("%d",&x);
        bool b = ListDelete(L,x,&y);
        if(b)   printf("删除成功!,删除的值为:%d\n",y);
        else    printf("删除失败!\n");
        break ;
    }
    case 4:{
        OutputList(L);
        break;
    }
    case 5:{
        int x;
        printf("请输入您要查看的位置:\n");
        scanf("%d",&x);
        GetElem(L,x);
        break ;
    }
    case 6:{
        int x;
        printf("请输入您要查找的元素的值:\n");
        scanf("%d",&x);
        int b = LocateElem(L,x);
        if(b)   printf("查找成功!,是第%d个元素\n",b);
        else    printf("查找失败!没有这个元素\n");
        break ;
    }
    case 7:{
        printf("现在顺序表的长度是:%d\n",L->length);
        break;
    }
    default:
        printf("输入错误,请重新输入:\n");
        break;
    }//of switch
    }//of while
}//of text2

int main(){

    SqList l;
    SqList *L=&l;
    InitList(L);
    text2(L);
   
}

4. Dynamic storage

The basic operation is similar to static storage, the difference lies in structure, initialization and increasing table length.

4.1 Structure writing

//顺序表数据元素结构体(静态分配)
typedef struct SqList
{
    //[1]用静态的“数组”存放数据元素
    Elemtype data[MaxSize];
    //[2]顺序表的当前长度
    int length;
}SqList;//顺序表的类型定义(静态分配方式)


//顺序表数据元素结构体(动态分配)
typedef struct SeqList
{
    //[1]指示动态分配数组的指针
    Elemtype *data;
    //[2]顺序表的当前长度
    int length;
    //[3]顺序表的最大容量
    int maxsize;
}SeqList;//顺序表的类型定义(动态分配方式)

4.2 Initialization

//基本操作----初始化一个静态顺序表
bool InitsqList(SqList *L){
    //[1]将所有数据元素设为默认初始值
    for(int i = 0; i < MaxSize; i++){
        L->data[i] = 0;
    }
    /*
    1.本步骤其实可以省略
    2.之所以赋初值是因为内存中会有遗留的"脏数据"
    3.但是常规操作下,用户无法访问大于
      当前表长的数据元素,所以可以在需要时再赋值
    */

    //[2]顺序表初始长度设为0
    L->length = 0;

    return true;
}

//基本操作----初始化一个动态顺序表
bool InitseqList(SeqList *L){
    //[1]用malloc函数申请一片连续的存储空间

    L->data = (Elemtype *)malloc(sizeof(Elemtype) * InitSize);
    //[2]表长和默认最大长度初始化
    L->length = 0;
    L->maxsize = InitSize;

    return true;
}

4.3 The dynamic table can increase the table length

//动态顺序表的加长
bool IncreaseSize(SeqList *L,int len)
{
    //[1]生成指向原来顺序表存储位置的指针
    int *p = L->data;
    //[2]为顺序表开辟一片比原来更大的空间
    L->data = (Elemtype *)malloc((L->maxsize + len) * sizeof(Elemtype));
    //[3]转移数据
    for (int i = 0; i < L->length; i++){
        L->data[i] = p[i];
    }
    //[4]修改顺序表的最大长度,为其增加len
    L->maxsize = L->maxsize + len;
    //[5]释放原来的存储空间
    free(p);

    return true;
}

4.4 Source code (static + dynamic storage)

//[1]定义顺序表最大长度和动态数组初始默认的最大容量
#define MaxSize 10      //静态顺序表的最大长度
#define InitSize 10     //动态顺序表的初始最大长度
//需要包含的头文件
#include <stdio.h>
#include <stdlib.h>
//C语言自定义bool变量
#define bool char
#define true 1
#define false 0
//自定义数据元素的数据类型
typedef int Elemtype;

//顺序表数据元素结构体(静态分配)
typedef struct SqList
{
    //[1]用静态的“数组”存放数据元素
    Elemtype data[MaxSize];
    //[2]顺序表的当前长度
    int length;
}SqList;//顺序表的类型定义(静态分配方式)

//顺序表数据元素结构体(动态分配)
typedef struct SeqList
{
    //[1]指示动态分配数组的指针
    Elemtype *data;
    //[2]顺序表的当前长度
    int length;
    //[3]顺序表的最大容量
    int maxsize;
}SeqList;//顺序表的类型定义(动态分配方式)

//基本操作----初始化一个静态顺序表
bool InitsqList(SqList *L)
{
    //[1]将所有数据元素设为默认初始值
    for(int i = 0; i < MaxSize; i++)
    {
        L->data[i] = 0;
    }
    /*
    1.本步骤其实可以省略
    2.之所以赋初值是因为内存中会有遗留的"脏数据"
    3.但是常规操作下,用户无法访问大于
      当前表长的数据元素,所以可以在需要时再赋值
    */

    //[2]顺序表初始长度设为0
    L->length = 0;

    return true;
}

//基本操作----初始化一个动态顺序表
bool InitseqList(SeqList *L)
{
    //[1]用malloc函数申请一片连续的存储空间
    L->data = (Elemtype *)malloc(sizeof(Elemtype) * InitSize);
    //[2]表长和默认最大长度初始化
    L->length = 0;
    L->maxsize = InitSize;

    return true;
}

//动态顺序表的加长
bool IncreaseSize(SeqList *L,int len)
{
    //[1]生成指向原来顺序表存储位置的指针
    int *p = L->data;
    //[2]为顺序表开辟一片比原来更大的空间
    L->data = (Elemtype *)malloc((L->maxsize + len) * sizeof(Elemtype));
    //[3]转移数据
    for (int i = 0; i < L->length; i++)
    {
        L->data[i] = p[i];
    }
    //[4]修改顺序表的最大长度,为其增加len
    L->maxsize = L->maxsize + len;
    //[5]释放原来的存储空间
    free(p);

    return true;
}

//基本操作----顺序表的插入
//[1]静态顺序表的插入
bool SqListInsert(SqList *L,int i,Elemtype e)
{
    //[1]判断i的合法性
    if(i < 1 || i > L->length + 1)
    {
        printf("The position of the element to be inserted is invalid!\n");
        return false;
    }
    if(L->length >= MaxSize)
    {
        printf("This sequence table is full!\n");
        return false;
    }

    //[2]将第i个元素及之后的元素都后移
    for(int j = L->length; j >= i; j--)
    {
        L->data[j] = L->data[j-1];      //第i个元素对应数组下标为i-1的数组元素 
    }
    //[3]在正确的位置插入新元素
    L->data[i-1] = e;
    //[4]顺序表长+1(注意:顺序表的最大长度不变)
    L->length++;
    //[5]插入成功,返回成功信号
    return true;
}
//[2]动态顺序表的插入
bool SeqListInsert(SeqList *L,int i,Elemtype e)
{
    //[1]判断i的合法性
    if(i < 1 || i > L->length + 1)
    {
        printf("The position of the element to be inserted is invalid!\n");
        return false;
    }
    if(L->length >= L->maxsize)
    {
        printf("This sequence table is full!\n");
        return false;
    }

    //[2]将第i个元素及之后的元素都后移
    for(int j = L->length; j >= i; j--)
    {
        L->data[j] = L->data[j+1];      //第i个元素对应数组下标为i-1的数组元素 
    }
    //[3]在正确的位置插入新元素
    L->data[i-1] = e;
    //[4]顺序表长+1(注意:顺序表的最大长度不变)
    L->length++;
    //[5]插入成功,返回成功信号
    return true;
}

//基本操作----顺序表的元素删除
//[1]静态顺序表的元素删除
bool SqListDelete(SqList *L, int i, Elemtype *e)
{
    //[1]判断i的合法性
    if(i < 1 || i > L->length + 1)
    {
        printf("The position of the element to be delected is invalid!\n");
        return false;
    }
    if(L->length <= 0)
    {
        printf("This sequence table is empty!\n");
        return false;
    }
    //[2]将被删除的元素值赋给e
    *e = L->data[i-1];
    //[3]将第i个元素及之后的元素都前移
    for(int j = i; j <= L->length; j++)
    {
        L->data[j-1] = L->data[j];      //第i个元素对应数组下标为i-1的数组元素 
    }
    //[4]顺序表长-1(注意:顺序表的最大长度不变)
    L->length--;
    //[5]插入成功,返回成功信号
    return true;
}
//[2]动态顺序表的元素删除
bool SeqListDelete(SeqList *L,int i,Elemtype *e)
{
        //[1]判断i的合法性
    if(i < 1 || i > L->length + 1)
    {
        printf("The position of the element to be delected is invalid!\n");
        return false;
    }
    if(L->length <= 0)
    {
        printf("This sequence table is empty!\n");
        return false;
    }
    //[2]将被删除的元素值赋给e
    *e = L->data[i-1];
    //[3]将第i个元素及之后的元素都前移
    for(int j = i; j <= L->length; j++)
    {
        L->data[j-1] = L->data[j];      //第i个元素对应数组下标为i-1的数组元素 
    }
    //[4]顺序表长-1(注意:顺序表的最大长度不变)
    L->length--;
    //[5]插入成功,返回成功信号
    return true;
}

//基本操作----按值查找
//[1]静态顺序表的按值查找
int SqListLocateElem(SqList L, Elemtype e)
{
    int i;
    for(i = 0; i < L.length; i++)
    {
        if (L.data[i] == e)
        {
            return i+1;
        }
    }
    return 0;
}
//[2]动态顺序表的按值查找
int SeqListLocateElem(SeqList L, Elemtype e)
{
    int i;
    for(i = 0; i < L.length; i++)
    {
        if (L.data[i] == e)
        {
            return i+1;
        }
    }
    return 0;
}

//额外操作----顺序表的打印
//[1]静态顺序表的输出
bool SqListPrint(SqList L)
{
    //[1]判空
    if(L.length == 0)
    {
        printf("This sequence table is empty!\n");
        return false;
    }
    //[2]输出
    printf("SqList:\n");
    for(int i = 0;i < L.length;i++)
    {
        printf("%d-->",L.data[i]);
    }
    printf("end\n");
}
//[2]动态顺序表的输出
bool SeqListPrint(SeqList L)
{
    //[1]判空
    if(L.length == 0)
    {
        printf("This sequence table is empty!\n");
        return false;
    }
    //[2]输出
    printf("SeqList:\n");
    for(int i = 0;i < L.length;i++)
    {
        printf("%d-->",L.data[i]);
    }
    printf("end\n");
}


int main()
{
    /*【1】生成顺序表*/
    //[1]静态分配的顺序表L1
    SqList L1;
    //[2]动态分配的顺序表L2
    SeqList L2;

    /*【2】顺序表的初始化*/
    //[1]静态顺序表L1的初始化
    InitsqList(&L1);
    //[2]动态顺序表L2的初始化
    InitseqList(&L2);

    /*【3】顺序表插入新元素*/
    int e;
    SqListInsert(&L1,1,1);
    SqListInsert(&L1,2,2);
    SqListInsert(&L1,3,3);
    SqListInsert(&L1,4,4);
    SqListInsert(&L1,5,5);
    SqListDelete(&L1,3,&e);
    SqListInsert(&L1,5,6);

    SeqListInsert(&L2,1,1);
    SeqListInsert(&L2,2,2);
    SeqListInsert(&L2,3,3);
    SeqListInsert(&L2,4,4);
    SeqListInsert(&L2,5,5);
    SeqListDelete(&L2,2,&e);
    SeqListInsert(&L2,5,6);
    IncreaseSize(&L2,5);

    SqListPrint(L1);
    SeqListPrint(L2);

    printf("%d\n",L2.maxsize);
    printf("SqListLocateElem(4) = %d\n",SqListLocateElem(L1,4));
    printf("SeqListLocateElem(6) = %d\n",SeqListLocateElem(L2,6));

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_58602552/article/details/131314173