[数据结构] 线性表-顺序存储

线性表

线性表是具有相同数据类型的n个数据元素的有限序列。n可以为0,这些数据元素在逻辑上有先后线性有序,因此叫线性表。

线性表的存储结构

  • 顺序存储:用地址连续的存储空间存储
  • 链式存储:用地址不一定连续的存储空间存储

顺序表的插入、删除、按值查找效率

线性表的链式存储结构

  • 单链表:表中每一个结点分为两部分,一部分是自己的数据,另一部分是指向下一个结点的指针域。
  • 双链表:表中每一个结点分为三部分,一部分是自己数据,一部分指向前一个结点,一部分指向后一个结点。
  • 循环链表:尾结点的指针域指向头结点不为NULL了。
  • 静态链表:用数组来描述,每个结点有两部分组成,一部分是自己数据,另外一部分表示下一个结点的数组下标(不是指针)

 

线性表的顺序存储结构实现

seqlist.h

#ifndef __SEQLIST_H__
#define __SEQLIST_H__

#include<cstdio>
#include<malloc.h>
#include<assert.h>
#define SEQLIST_INIT_SIZE 8
#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 x); //在顺序表的末尾插入元素
void push_front(Seqlist *list, ElemType x); //在顺序表的头部插入元素
void show_list(Seqlist *list); //显示顺序表中的元素
void pop_back(Seqlist *list); //删除顺序表最后一个元素
void pop_front(Seqlist *list); //删除顺序表第一个元素
void insert_pos(Seqlist *list, int pos, ElemType x);//在顺序表的选定位置上插入数据
int find(Seqlist *list, ElemType key); //在顺序表中查找元素key的下标
int length(Seqlist *list);//求顺序表的长度
void delete_pos(Seqlist *list, int pos); //删除顺序表中特定位置的数据元素
void delete_val(Seqlist *list, int key);//删除顺序表中值为key的数据元素
void sort(Seqlist *list);//冒泡排序
void reverse(Seqlist *list);//逆置顺序列表
void clear(Seqlist *list);//清除顺序表中的所有元素
void destroy(Seqlist *list);//摧毁顺序表
void merge(Seqlist *lt, Seqlist *la, Seqlist *lb);//合并两个顺序列表

#endif //__SEQLIST_H__

seqlist.cpp

#include"seqlist.h"

bool Inc(Seqlist *list) {
    ElemType *newbase = (ElemType*)realloc(list, sizeof(ElemType)*(list->capacity + INC_SIZE));  //重新分配内存空间
    if (newbase == NULL) {
        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 x) {
    if (list->size >= list->capacity && !Inc(list)) { //Inc(list)用来判断增加顺序表容量是否成功,只有在失败的情况下才会进入if语句中
        printf("顺序表容量已满,无法再在表尾继续插入新元素!\n");
        return;
    }
    list->base[list->size] = x;
    list->size++;
}

void push_front(Seqlist *list, ElemType x) {
    if (list->size >= list->capacity && !Inc(list)) {
        printf("顺序表容量已满,无法再在表头插入新元素!\n");
        return;
    }
    for (int i = list->size;i > 0;i--) {
        list->base[i] = list->base[i - 1];
    }
    list->base[0] = x;
    list->size++;
}

void show_list(Seqlist *list) {
    for (int i = 0;i < list->size;i++) {
        printf("%d ", list->base[i]);
    }
    printf("\n");
}

void pop_back(Seqlist *list) {
    if (list->size == 0) {
        printf("顺序表已空,无法再在表尾删除元素!\n");
        return;
    }
    list->size--;
}

void pop_front(Seqlist *list) {
    if (list->size == 0) {
        printf("顺序表已空,无法再在表头删除元素!\n");
        return;
    }
    for (int i = 0;i < list->size - 1;i++) {
        list->base[i] = list->base[i + 1];
    }
    list->size--;
}

void insert_pos(Seqlist *list, int pos, ElemType x) {
    if (pos<0 || pos>list->size) {
        printf("插入位置不合法,无法插入元素!\n");
        return;
    }
    if (list->size >= list->capacity && !Inc(list)) {
        printf("顺序表容量已满,无法在插入新的元素!\n");
        return;
    }
    for (int i = list->size;i > pos;i--) {
        list->base[i] = list->base[i - 1];
    }
    list->base[pos] = x;
    list->size++;
}

int find(Seqlist *list, ElemType key) {
    for (int i = 0;i < list->size;i++) {
        if (list->base[i] == key)
            return i;
    }
    return -1;
}

int length(Seqlist *list) {
    return list->size;
}

void delete_pos(Seqlist *list, int pos) {
    if (pos < 0 || pos >= list->size) {
        printf("删除位置不合法,无法删除元素!\n");
        return;
    }
    for (int i = pos;i < list->size - 1;i++) {
        list->base[i] = list->base[i + 1];
    }
    list->size--;
}

void delete_val(Seqlist *list, int key) {
    int pos = find(list, key);
    if (pos == -1) {
        printf("顺序表中没有这个元素!\n");
        return;
    }
    delete_pos(list, pos);
}

void sort(Seqlist *list) {
    for (int i = 0;i < list->size - 1;i++) {//排序的趟数(例如5个数据需要比较4趟)
        for (int j = 0;j < list->size - 1 - i;j++) {//每一趟比较中的比较次数(例如5个数据在第0趟需要比较4次)
            if (list->base[j] > list->base[j + 1]) {
                ElemType temp = list->base[j];
                list->base[j] = list->base[j + 1];
                list->base[j + 1] = temp;
            }
        }
    }
}

void reverse(Seqlist *list) {
    if (list->size == 0 || list->size == 1) return;
    int low = 0, high = list->size - 1;
    while (low < high) {
        ElemType temp = list->base[low];
        list->base[low] = list->base[high];
        list->base[high] = temp;
        low++;
        high--;
    }
}

void clear(Seqlist *list) {
    list->size = 0;
}

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

void merge(Seqlist *lt, Seqlist *la, Seqlist *lb) {
    lt->capacity = la->size + lb->size;
    lt->base = (ElemType*)malloc(sizeof(ElemType)*lt->capacity);
    assert(lt->base != NULL);

    int ia = 0, ib = 0, ic = 0;
    while (ia < la->size&&ib < lb->size) {
        if (la->base[ia] < lb->base[ib]) {
            lt->base[ic++] = la->base[ia++];
        }
        else {
            lt->base[ic++] = lb->base[ib++];
        }
    }
    while (ia < la->size) {
        lt->base[ic++] = la->base[ia++];
    }
    while (ib < lb->size) {
        lt->base[ic++] = lb->base[ib++];
    }
    lt->size = la->size + lb->size;
    show_list(lt);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值