【数据结构学习】- 顺序表

用C语言实现顺序表,包括:

1、顺序表初始化;

2、顺序表添加元素;

3、顺序表删除元素;

4、顺序表查找元素;

5、替换元素;

6、几个小算法:

        1)顺序表翻转

        2)合并顺序表

        3)对比获取两个顺序表较小元素

        4)顺序表去重

        5)顺序表中最大值和最小值

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

#define Size 10 // 对Size进行宏定义,表示顺序表申请空间大小

typedef struct Table {
    int* head; // 指向顺序表第一个元素的指针
    int length; // 顺序表的当前长度
    int size; // 顺序表的最大容量
} table;

table initTable() {
    table t;
    t.head = (int*)malloc(Size * sizeof(int)); // 构造一个空的顺序表,动态申请存储空间
    if (!t.head) { // 申请失败,直接退出
        printf("初始化失败");
        exit(0);
    }
    t.length = 0; // 空表的长度初始化为0
    t.size = Size; // 空表的初始存储空间为Size
    return t;
}

void displayTable(table t) {
    for (int i = 0; i < t.length; i++) {
        printf("%d\n", t.head[i]);
    }
    printf("\n");
}

// 插入函数,elem为插入的元素,add为插入到顺序表的位置
table addTable(table t, int elem, int add) {
    // 判断插入本身是否存在问题
    // 如果插入元素位置比整张表的长度+1还大,or插入位置本身不存在,退出
    if (add > t.length + 1 || add < 1) {
        printf("插入位置有问题\n");
        return t;
    }
    // 插入操作时,判断顺序表是否有多余的存储空间提供给插入的元素,如果没有,就需要申请
    if (t.length == t.size) {
        t.head = (int*)realloc(t.head, (t.size + 1) * sizeof(int));
        if (!t.head) {
            printf("存储分配失败\n");
            return t;
        }
        t.size += 1;
    }
    // 插入时,需要将从插入位置开始的后续元素,逐个后移
    for (int i = t.length - 1; i >= add - 1; i--)
    {
        t.head[i + 1] = t.head[i];
    }
    // 后移完成后,直接将所需插入元素,添加到顺序表的对应位置
    t.head[add - 1] = elem;
    // 长度+1
    t.length++;
    return t;
}

// 删除元素
table delTable(table t, int add) {
    if (add > t.length || add < 1) {
        printf("被删除元素位置有误");
        return t;
    }

    for (int i = add; i < t.length; i++)
    {
        t.head[i - 1] = t.head[i];
    }
    t.length--;
    return t;
}

// 查找元素
int selectTable(table t, int elem) {
    for (int i = 0; i < t.length; i++)
    {
        if (t.head[i] == elem) {
            return i + 1;
        }
    }
    return    -1;
}

// 查找替换
table amendTable(table t, int elem, int newElem) {
    int add = selectTable(t, elem);
    t.head[add - 1] = newElem;
    return t;
}

// 顺序表翻转【LOW】:时间复杂度 O(n^2), 空间复杂度O(n^2)
table reversal(table t) {
    table new_t = initTable();
    int len = t.length;
    for (int i = t.length - 1; i >= 0; i--)
    {
        new_t = addTable(new_t, t.head[i], len - i);
    }
    return new_t;
}

// 顺序表翻转 ***** 时间复杂度O(n), 空间复杂度O(1)
table newReversal(table t) {
    int left = 0;
    int right = t.length - 1;
    while (left < right)
    {
        int temp = t.head[left];
        t.head[left] = t.head[right];
        t.head[right] = temp;
        left++;
        right--;
    }
    return t;
}


// ***** 合并两个顺序表,时间复杂度O(m+n),空间复杂度O(m+n)
table mergeTable(table t1, table t2) 
{
    int len1 = t1.length;
    int len2 = t2.length;
    table new_t;
    new_t.head = (int*)malloc((len1 + len2) * sizeof(int));
    new_t.size = len1 + len2;
    new_t.length = 0;
    int p1 = 0;
    int p2 = 0;
    int new_p = 0;
    while (p1 < len1 && p2 < len2)
    {
        if (t1.head[p1] <= t2.head[p2]) {
            new_t.head[new_p] = t1.head[p1];
            p1++;
        } else {
            new_t.head[new_p] = t2.head[p2];
            p2++;
        }
        new_p++;
        new_t.length++;
    }
    while (p1 < len1) {
        new_t.head[new_p] = t1.head[p1];
        p1++;
        new_p++;
        new_t.length++;
    }

    while (p2 < len2) {
        new_t.head[new_p] = t2.head[p2];
        p2++;
        new_p++;
        new_t.length++;
    }

    return new_t;
}

// 获取两个顺序表中较小的元素
table compareTable(table t1, table t2) {
    int len1 = t1.length;
    int len2 = t2.length;
    int cp_len = 0;
    if (len1 > len2) {
        cp_len = len2;
    } else {
        cp_len = len1;
    }
    table cp_t;
    cp_t.head = (int*)malloc(cp_len * sizeof(int));
    cp_t.size = cp_len;
    cp_t.length = 0;
    int p1 = 0;
    int p2 = 0;
    int cp = 0;
    while (p1 < len1 && p2 < len2)
    {
        if (t1.head[p1] < t2.head[p2]) {
            cp_t.head[cp] = t1.head[p1];
        } else {
            cp_t.head[cp] = t1.head[p2];
        }
        p1++;
        p2++;
        cp++;
        cp_t.length++;
    }
    return cp_t;
}

// 顺序表去重 时间复杂度O(n), 空间复杂度O(1)
table delSame(table t) {

    int len     = t.length;
    int new_index = 1;
    for (int j = 1; j < len; j++)
    {
        if (t.head[j-1] == t.head[j]) {
            t.head[new_index] = t.head[j];
            t.length--;
            new_index++;
        } 
    }
    return t;
}

// 查询顺序表中的最大值和最小值,时间复杂度O(n),空间复杂度O(1)
void getMaxAndMin(table t) {
    int min = t.head[0];
    int max = t.head[0];
    for (int i = 0; i < t.length; i++)
    {
        if (min > t.head[i])
        {
            min = t.head[i];
        }

        if (max < t.head[i])
        {
            max = t.head[i];
        }
    }
    printf("最小值:%d\n", min);
    printf("最大值:%d\n", max);
}

int main() {
    table t = initTable();

    for (int i = 1; i <= Size; i++)
    {
        t.head[i - 1] = i;
        t.length++;
    }

    displayTable(t);
    t = delTable(t, 1);
    displayTable(t);
    t = addTable(t, 99, 2);
    displayTable(t);
    getMaxAndMin(t);

    t = amendTable(t, 99, 100);
    displayTable(t);
    t = reversal(t);
    displayTable(t);
    t = newReversal(t);

    delTable(t, 2);
    displayTable(t);
    table new_t = initTable();
    for (int i = 0; i < 8; i++)
    {
        new_t.head[i] = 3 + i;
        new_t.length++;
    }
    displayTable(new_t);
    table merge_t = mergeTable(t, new_t);
    displayTable(merge_t);
    // table cp_t = compareTable(t, new_t);
    // displayTable(cp_t);
    table only_t = delSame(merge_t);
    displayTable(only_t);
    getMaxAndMin(only_t);
    return 0;
}

参考:C语言中文网 - 顺序表(顺序存储结构)及初始化详解

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值