线性表的实现及其基本操作

  1. 线性表的定义
    线性表是最简单最常用的一种数据结构,它是一种能在任意位置进行插入和删除数据元素操作的、由n(n>=0)个相同数据元素组成的线性结构。
  2. 线性表的抽象数据类型
    数据集合
    线性表的数据集合可以表示为a0, a1, a2, a3, ……, an-1,每个数据元素的数据类型都是抽象数据元素的数据类型ElemType。
    操作集合(在此仅罗列一部分,详细内容请看代码块)
    a. 初始化 InitiateList(L):初始化线性表L
    b. 求当前数据元素个数ListLebgth(L)
    c. 插入数据元素ListInset(L, i, x): 在线性表L的第i个数据元素前插入数据元素x
    d. 删除数据元素ListDelete(L, i, x):删除线性表第i个数据元素x
    e. 取数据元素ListGet(L, i, x): 取线性表的第i个数据元素x
//顺序表相关操作头文件
#define  ElemType  int
#include<malloc.h>
#include<string.h>

#define SIZE 10
#define NEWSIZE 4

typedef struct SeqList
{
    ElemType *base;      //顺序表空间,指的是为顺序表在内存中动态申请的空间
    size_t capacity;     //顺序表的容量
    size_t length;       //顺序表的长度,即元素的个数
}SeqList;


int NewSpace(SeqList *list)  //尾插时需要申请新的空间 
{
    ElemType *newspace = (ElemType*)malloc(sizeof(ElemType)*(list->capacity + NEWSIZE));
    if(newspace == NULL)
    {
        printf("Out Of Memory!\n");  
        return 0;
    }
    memcpy(newspace, list->base, sizeof(ElemType)*list->capacity);   //将新申请的空间作为新的顺序表空间,并且将原来的顺序表空间释放
    free(list->base);
    list->base = newspace;
    list->capacity += NEWSIZE;
    return 1;
}

void InitSeqList(SeqList *list)  //顺序表的初始化
{
    list->capacity = SIZE;
    list->base = (ElemType *)malloc(sizeof(ElemType)*list->capacity);
    list->length = 0;
}

int BegInsert(SeqList *list, ElemType a) //头插元素
{
    if(list->length >= list->capacity)  //判断顺序表的长度是否大于容量
    {
        printf("空间已满,不能插入!\n");
        return 0;
    }
    if(NULL == list->base)           //判断顺序表是否被置空  如果已经置空就不能插入数据
    {
        printf("out  of memory\n");
        return 0;
    }
    for(int i=list->length; i>0; i--)
    {
        list->base[i] = list->base[i-1];
    }
    list->base[0] = a;
    list->length++;
    return 1;
}

int EndInsert(SeqList *list, ElemType a)   //尾插元素
{
    if(NULL == list->base)           //判断顺序表是否被置空  如果已经置空就不能插入数据
    {
        printf("out  of memory\n");
        return 0;
    }
    if(list->length >= list->capacity && !NewSpace(list)) //判断插入后顺序表的长度是否大于容量,是否与新申请的空间大小不符
    {
        printf("空间已满,无法插入!\n");
        return 0;
    }
    list->base[list->length++] = a;     //把插入的值赋给顺序表增加的新空间
    return 1;
}
void ShowList(SeqList *list)         //顺序表的显示
{
    for(int i=0; i<list->length; i++)
    {
        printf("%d ",list->base[i]);
        printf(" ");
    }
    printf("\n");;
}

int BegDelete(SeqList *list) // 头删元素
{
    if(list->length == 0)     // 判断是否非空
    {
        printf("顺序表已空,无数据可删!\n");
        return 0;
    }
    for(int i=0; i<list->length-1; i++)  // 头删只需让顺序表中的元素从后往前逐个移动
    {
        list->base[i] = list->base[i+1];
    }
    list->length--;
    return 1;
}

int EndDelete(SeqList *list) //尾删元素
{
    if(list->length == 0)
    {
        printf("顺序表已空,无数据可删!\n");
        return 0;
    }
    list->length--;      // 尾部删除只需将顺序表的长度减一即可
    return 1;
}

void SortList(SeqList *list)       //对顺序表内的数据排序----冒泡排序法
{
    int i, j;
    for(i=0; i<list->length; i++)
    {
        for(j=0; j<list->length-i-1; j++)
        {
            if(list->base[j] > list->base[j+1])
            {
                int temp = list->base[j];
                list->base[j] = list->base[j+1];
                list->base[j+1] = temp;
            }
        }
    }
}

int InsertBVal(SeqList *list, ElemType a) //在顺序表中按值插入数据
{
    if(list->length >= list->capacity)  //判断顺序表的长度是否大于容量
    {
        printf("空间已满,不能插入!\n");
        return 0;
    }
    if(list->length == 0)               //如果顺序表是空的,则将插入的值当做第一个数
    {
        list->base[0] = a;
    }
    else
    {
        int pos;
        for(pos=0; pos<list->length; pos++)
        {
            if(list->base[pos] > a)               //  找到pos的位置然后跳出
                break;
        }
        for(int i=list->length; i>pos; i--)
        {
            list->base[i] = list->base[i-1];
        }
        list->base[pos] = a;
    }
    list->length++;
    return 1;
}

int InsertBPos(SeqList *list, int pos, ElemType a)   //按照位置插入数据
{
    if(list->length >= list->capacity)  //判断顺序表的长度是否大于容量
    {
        printf("空间已满,不能插入!\n");
        return 0;
    }
    if(pos<0 || pos>list->length)
    {
        printf("插入元素位置出错!\n");
        return 0;
    }
    for(int i=list->length; i>pos; i--)   //找出pos的位置,然后将pos到顺序表末尾的数据逐个向后移动,最后在pos处将a插入
    {
        list->base[i] = list->base[i-1];
    }
    list->base[pos] = a;
    list->length++;
    return 1;
}

int DelByPos(SeqList *list, int pos)     //按照位置删除元素
{
    int i;
    if(list->length == 0)
    {
        printf("顺序表已空,无数据可删!\n");
        return 0;
    }
    for(i=0; i<pos; i++)
    {
        if(i == pos)
            break;
    }
    for(i=pos; i<list->length; i++)
    {
        list->base[i] = list->base[i+1];
    }
    list->length--;
    return 1;
}

int DelByValue(SeqList *list, ElemType a)     // 根据数值删除顺序表中的元素
{
    int i, j;
    if(list->length == 0)
    {
        printf("顺序表已空,无数据可删!\n");
        return 0;
    }
    for(i=0; i<list->length; i++)
    {
        if(list->base[i] == a)        // 找到要删除的数据
            break;
    }
    for(j=i; j<list->length; j++)    //将要删除的数据之后的数据逐个向前移动 
    {
        list->base[j] = list->base[j+1];
    }
    list->length--;
    return 1;
}

void FindElem(SeqList *list, ElemType a)       //查找顺序表中的某一数据
{
    int i;
    if(list->length ==0)
    {
        printf("顺序表为空,没有数据!\n");
        return;
    }
    else 
    {
        for(i=0; i<list->length; i++)
        {
            if(list->base[i] == a)         //找到要查找的数据的位置跳出循环,输出结果
                break;
        }
        printf("该数据在顺序表的%d的位置处\n",i);
    }
}

int ListLength(SeqList *list)             //求顺序表中的数据个数
{
    printf("该顺序表中有%d个数据\n",list->length); // 将顺序表的长度打印出来即可
    return 1;
}

void CleanList(SeqList *list)      //顺序表的清空, 让顺序表的长度为零即可
{
    if(list->length == 0)
    {
        printf("顺序表为空!\n");
    }
    else
    {
        list->length = 0;
        printf("顺序表已清空!\n");
    }
}

void ReverseShow(SeqList *list)   //顺序表的逆序输出 
{
    if(list->length == 0)
    {
        printf("顺序表为空!\n");
    }
    else
    {
        for(int i=list->length-1; i>=0; --i)   //注意循环条件 顺序表的下标从0开始
        {
            printf("%d ",list->base[i]);
        }
        printf("\n");
    }
}

void DestroyList(SeqList *list) //顺序表的销毁
{
    free(list->base);              //顺序表的内存是连续的,只需要将它的空间释放后再置空就行
    list->base = NULL;
}
#include<stdio.h>
#include"SeqList.h"


//顺序表操作测试
void main()
{
    SeqList list;
    InitSeqList(&list);

    ElemType x;
    int pos;
    int select = 1;
    while(select)
    {
        printf("*************************************************\n");
        printf("*[1] BegInsert   [2] EndInsert   [3] ShowList   *\n");
        printf("*[4] BegDelete   [5] EndDelete   [6] SortList   *\n");
        printf("*[7] InsertBPos  [8] InsertBVal  [9] DelByPos   *\n");
        printf("*[10]DelByValue  [11]FindElem    [12]ListLength *\n");
        printf("*[13]CleanList   [14]ReverseShow [15]DestroyList*\n");
        printf("*************** [0] QuitSystem ******************\n");
        printf("*************************************************\n");
        printf("请选择:  ");
        scanf("%d",&select);
        switch(select)
        {
        case 0:
            break;
        case 1:
            printf("请输入要插入的数据(以-1结束):> ");
            while(scanf("%d",&x),x != -1)
            {
                BegInsert(&list, x);
            }
            break;
        case 2:
            printf("请输入要插入的数据(以-1结束):> ");
            while(scanf("%d",&x),x != -1)
            {
                EndInsert(&list, x);
            }
            break;
        case 3:
            ShowList(&list);
            break;
        case 4:
            BegDelete(&list);
            break;
        case 5:
            EndDelete(&list);
            break;
        case 6:
            SortList(&list);
            break;
        case 7:
            printf("请输入要插入的数据:> ");
            scanf("%d",&x);
            printf("请输入要插入的位置:> ");
            scanf("%d",&pos);
            InsertBPos(&list, pos, x);
            break;
        case 8:
            SortList(&list);
            printf("请输入要插入的数据:> ");
            scanf("%d",&x);
            InsertBVal(&list, x);
            break;
        case 9:
            printf("请输入位置:> ");
            scanf("%d",&pos);
            DelByPos(&list, pos);
            break;
        case 10:
            printf("请输入要删除的元素:> ");
            scanf("%d",&x);
            DelByValue(&list, x);
            break;
        case 11:
            printf("请输入要查找的数据:> ");
            scanf("%d", &x);
            FindElem(&list, x);
            break;
        case 12:
            ListLength(&list);
            break;
        case 13:
            CleanList(&list);
            break;
        case 14:
            ReverseShow(&list);
            break;
        case 15:
            DestroyList(&list);
            break;
        }
    }

}
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值