c语言--线性表之顺序表

1 SeqList.c

1.1 顺序表特点

顺序表是在连续空间中存储的同类型元素。

除了首尾元素只有后继和前驱,中间的每个元素都有前驱和后继,因此知道首元素存储的位置,其它元素的位置迅速搜索到。loc(ai)=loc(a0)+(i-0)*(数据类型字节)。小明一班20人按照名次住同一层,每人一个房间,且房间相连。小明为第一名,宿舍号为123,小亮为第五名,他的房间号为123+(5-1)=127。
顺序表优缺点:
顺序表搜索元素时间复杂度为O(1),但是在插入、删除元素时需要挪动元素,最差的时间复杂的为O(n)。除此之外,顺序表需要要占据连续的空间。

1.2 顺序表初始化

顺序表有多个属性,因此用结构体初始化。顺序表的属性包括数组、容量、元素数量。数组用来存储元素,容量表示顺序表最大储存元素的数量,元素数量是实际储存元素数量。
可以静态初始化,也可以动态初始化。静态初始化直接在栈空间确定一个连续的空间。动态初始化是通过指定类型指针在堆空间动态分配内存,内存的大小可以根据需要再进行调整,使用后要手动释放内存。

1.3 从顺序表末尾添加元素

因为要对顺序表内容调整,因此输入参数为顺序表地址。a. 判断顺序表是否满员。b. 如果顺序表未满员,取出顺序表元素数量,在最后一个元素添加到表中,同时元素数量+1。

1.4 从顺序表表首添加元素

a.判断顺序表是否满员。b.上一判断不成立,从后n-1向前遍历到0,每个元素都向后挪动一个位置,空出第一个元素。c. 把输入元素放在第一个位置上,同时元素数量+1。

1.5 列举顺序表

根据元素数量遍历顺序表,打印每个元素的数值。

1.6 从顺序表末尾删除元素

顺序表元素数量减一,这样最后一个元素无效。

1.7 从顺序表表首删除元素

a. 从第二个元素到最后一个元素,每个元素向前挪动一位。b.顺序表元素数量减一。

1.8 在顺序表指定位置插入元素

a. 判断位置是否合理。b.上一条件满足,指定位置上及之后的元素都向后挪动一个位置。b.把插入元素放在指定位置。d. 顺序表元素数量+1。

1.9 查找元素

遍历顺序表,判断每个元素是否跟查找元素是否相同。如果查找到,就返回对应元素的下标;反之,返回-1。

1.20 返回顺序表长度

返回顺序表长度。

1.21 删除顺序表指定位置元素

a. 顺序表指定位置之后的数据都向前挪动一位。b. 顺序表元素数量-1。

1.22 删除顺序表指定值

a. 用24的函数判断元素在顺序表的位置。b.如果元素在顺序表中,用26函数删除元素。

1.23 对顺序表排序

用冒泡法对数据排序。

1.24 清除顺序表

a.释放堆空间。b.指针为空值。

总结:通过以上代码,可以发现指针和循环用的多。a.用指针对顺序表元素修改。遍历主要用在罗列、删除、插入、查找中。b. 顺序表根据下标查找元素非常方便,但是删除、查找比较麻烦,还需要连续的存储空间。链表的优缺点与线性表正好相反。数据量不大,顺序表可以考虑。

//
//  SeqList.c
//  21days study C language
//
//  Created by ls .
//  Copyright © 2022 LSC001. All rights reserved.
//

#include "SeqList.h"

bool Inc(SeqList *list)
{
    ElemType *newbase = (ElemType*)realloc(list->base, sizeof(ElemType)*(list->capacity+INC_SIZE));
    if(NULL == newbase)
    {
        printf("内存不足,分配空间失败!\n");
        return false;
    }
    list->base = newbase;
    list->capacity += INC_SIZE;
    return true;
}

void InitSeqList(SeqList *list)
{
    list->base = (ElemType *)malloc(sizeof(ElemType)*SEQLIST_INIT_SIZE); // 线性表开辟空间
    assert(list->base != NULL);                                          // 判断空间是否开辟成功
    list->capacity = SEQLIST_INIT_SIZE;
    list->size = 0;
}

void push_back(SeqList *list,ElemType item)
{
    if (list->size >= list->capacity && !Inc(list))
    {
        printf("空间已满,不能插入!");
        return;
    }
    else
    {
        list->base[list->size]=item;
        list->size++;
    }
}

void push_front(SeqList *list,ElemType item)
{
    int i;
    if (list->size>=list->capacity && !Inc(list))
    {
        printf("空间已满,不能插入!");
        return;
    }
    i=list->size;
    while(i>0)
    {
        list->base[i]=list->base[i-1];
        i--;
    }
    list->base[0]=item;
    list->size++;
}

void show_list_(SeqList list)
{
    int i = 0;
    for (i=0;i<list.size;++i)
    {
        printf("%d  ",list.base[i]);
    }
}

void pop_back(SeqList *list)
{
    if(0 == list->size) return;
    list->size--;
}

void pop_front(SeqList *list)
{
    int i ;
    if(0 == list->size) return;

    for(i=1;i<list->size;++i)
    {
        list->base[i-1]=list->base[i];
    }
    list->size--;
}

void insert_pos(SeqList *list,int pos,ElemType item)
{
    if((pos<0 || pos>list->size) )
    {
        printf("输入位置数值无效!");
        return;
    }

    if (list->size >= list->capacity && !Inc(list))
    {
        printf("空间已满,不能插入!");
        return;
    }
    
    for(int i=list->size-1;i>=pos-1;--i)
    {
        list->base[i+1]=list->base[i];
    }
    list->base[pos-1] = item;
    list->size ++;
}


int find(SeqList list, ElemType item)
{
    int i,j=-1;
    for(i=0;i < list.size;++i)
    {
        if (item == list.base[i])
        {
            j=i;
            break;
        }
    }
    return j;
}

int length(SeqList list)
{
    return list.size;
}

void delete_pos(SeqList *list,int pos)
{
    int i ;
    if(pos<0 || pos>list->size)
    {
        printf("pos数据不能为负数");
    }else
    {
        for(i = pos;i<list->size;i++)
        {
            list->base[i-1] = list->base[i];
        }
        list->size--;
    }
}

void delete_value_(SeqList *list,ElemType value)
{
    int i = find(*list,value);
    if(-1 == i)
    {
        printf("NO VALUE IN SeqList");
        return;
    }
    delete_pos(list,i+1);
}

void sort(SeqList *list)
{
    int len = list->size;
    int i,j;
    ElemType tmp;
    for(i=0;i<len-1;++i)
    {
        for(j=0;j<len-1-i;++j)
        {
            if(list->base[j] > list->base[j+1])
            {
                tmp = list->base[j];
                list->base[j] = list->base[j+1];
                list->base[j+1] = tmp;
            }
        }
    }
}

void reverse(SeqList *list)
{
    int i,j;
    ElemType tmp;
    if(list->size <= 1)
    {
        return;
    }else
    {
        for(i=0,j=list->size-1;i<=(list->size)/2;i++,--j)
           {
               tmp = list->base[i];
               list->base[i] = list->base[j];
               list->base[j] = tmp;
           }
    }
}

void clear_(SeqList *list)
{
   list->size = 0;
}

void destroy_(SeqList *list)
{
    free(list->base);    
    list->base=NULL;
    list->capacity = 0;
    list->size = 0;
}


2 SeqList.h

//
//  SeqList.h
//  21days study C language
//
//  Created by ls.
//  Copyright © 2022 LSC001. All rights reserved.
//

#ifndef SeqList_h
#define SeqList_h

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

#define SEQLIST_INIT_SIZE 5    //  线性表初始化长度
#define INC_SIZE          3      //  线性表扩充空间
typedef int   ElemType;          //  线性表储存数据类型

typedef struct SeqList
{
    ElemType *base;              //  数组指针,即数组首元素地址
    int      capacity;           //  数组容量
    int      size;               //  数组数据量
}SeqList;

bool Inc(SeqList *list);                                // 扩充线性表
void InitSeqList(SeqList *list);                        // 声明线性表初始化函数
void push_back(SeqList *list,ElemType item);            // 线性表尾部插入数据item
void push_front(SeqList *list,ElemType item);           // 线性表头部插入数据item
void show_list_(SeqList list);                          // 列举线性表
void pop_back(SeqList *list);                           // 删除线性表最后一个元素
void pop_front(SeqList *list);                          // 删除线性表首元素
void insert_pos(SeqList *list,int pos,ElemType item);   // 在指定位置插入元素
int find(SeqList list, ElemType item);                  // 查找元素
int length(SeqList list);                               // 返回线性表长度
void delete_pos(SeqList *list,int pos);                 // 删除指定位置元素
void delete_value_(SeqList *list,ElemType value);       // 删除指定值
void sort(SeqList *list);                               // 对线性表排序
void reverse(SeqList *list);                            // 线性表元素翻转
void clear_(SeqList *list);                             // 清除线性表
void destroy_(SeqList *list);                           // 销毁线性表

#endif /* SeqList_h */




3 main.c

#include "SeqList.h"

int  main()
{
    SeqList mylist;            // 结构体变量
    InitSeqList(&mylist);      // 初始化线性表
    
    ElemType item;             // 线性表插入或删除的数值
    int pos;                   // 位置信息
    int select=1;              // 对线性表操作的初始化数值
    while(select)
    {
        printf("\n");
        printf("*********************************************\n");
        printf("* [1]  push_back          [2]  push_front   *\n");
        printf("* [3]  show_list_         [4]  pop_back     *\n");
        printf("* [5]  pop_front          [6]  insert_pos   *\n");
        printf("* [7]  find               [8]  length       *\n");
        printf("* [9]  delete_pos         [10] delete_value *\n");
        printf("* [11] sort               [12] reverse      *\n");
        printf("* [13] clear_             [14*] destroy     *\n");
        printf("* [15] quit_system                          *\n");
        printf("*********************************************\n");
        
        printf("请选择:-> ");
        scanf("%d",&select);
        if(0 == select) break;
        switch (select) {
            case 1:
            {
                printf("请选择输入 item 数值:");
                scanf("%d",&item);
                push_back(&mylist,item);
                show_list_(mylist);
                break;
            }
            case 2:
            {
                printf("请选择输入 item 数值:");
                scanf("%d",&item);
                push_front(&mylist,item);
                show_list_(mylist);
                break;
            }
            case 3:
            {
                show_list_(mylist);
                break;
            }
            case 4:
            {
                pop_back(&mylist);
                show_list_(mylist);
                break;
            }
            case 5:
            {
                pop_front(&mylist);
                show_list_(mylist);
                break;
            }
            case 6:
            {
                
                printf("请选择输入 pos,item 数值:\n");
                scanf("%d,%d",&pos,&item);
                insert_pos(&mylist,pos,item);
                show_list_(mylist);
                break;
            }
            case 7:
            {
                printf("请选择输入item 数值:\n");
                scanf("%d",&item);
                int i = find(mylist,item);
                printf("item的下标为:%d\n",i);
                break;
            }
            case 8:
            {
                int len = length(mylist);
                printf("list.size:%d\n",len);
                break;
            }
            case 9:
            {
                printf("请选择输入pos 数值:\n");
                scanf("%d",&pos);
                delete_pos(&mylist,pos);
                show_list_(mylist);
                break;
            }
            case 10:
            {
                int value;
                printf("请选择输入value 数值:\n");
                scanf("%d",&value);
                delete_value_(&mylist,value);
                break;
            }
            case 11:
            {
                sort(&mylist);
                show_list_(mylist);
                break;
            }
            case 12:
            {
                reverse(&mylist);
                show_list_(mylist);
                break;
            }
            case 13:
            {
                clear_(&mylist);
                show_list_(mylist);
                break;
            }
//            case 14:
//            {
//                destroy_(&mylist);
//                break;
//            }
            case 15:
            {
                
                break;
            }
            default:
                printf("输入错误,请重新输入。");
                break;
        }
    }
    destroy_(&mylist);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值