数据结构-顺序表-代码

顺序表 - 用顺序存储的方式实现线性表

定义

  • 通过数据元素的大小 + 线性表首元素的地址 == 定位顺序表的元素位置

    数据元素的大小:sizeof(Elem Type) 会返回一个 值=Elem 的大小

  • 特点

    随机访问:O(1)时间找到指定位置的元素

    存储密度高:每个节点只存储数据元素,(不存在指针等占用空间)

    拓展容量不方便

    数据的增删操作不方便

顺序表的静态分配

#include <stdio.h>
#include <iostream>
using namespace std;

#define MAXSIZE 20	//宏定义最大长度 

typedef int ElemType; //定义数据类型 

struct SqTable
{
    ElemType data[MAXSIZE]; // 存储静态表中的数据
    int length; // 静态表中元素的个数
};

// 初始化,对于静态表,在结构体定义的时候就已经声明了数据空间
void SqTableInit(SqTable* sq_table)
{
    for (int temp = 0; temp < MAXSIZE; temp++)
    {
        sq_table->data[temp] = 0;   // 数据初始化
    }
    sq_table->length = 0;   // 长度置0
}

// 数据初始化
bool SqTableInitData(SqTable* sq_table)
{
    cout << "Please cin the number of sequence element" << endl;
    cin >> sq_table->length;    // 输入静态表元素的个数
    if (sq_table->length > MAXSIZE)
    {
        cout << "too many element" << endl; // 元素个数超范围
        sq_table->length = 0;
        return false;
    }
    cout << "Please cin the element of sequence" << endl;
    for (int temp = 0; temp < sq_table->length; temp++) // 输入顺序表元素
    {
        cin >> sq_table->data[temp];
    }
    return true;
}

// 向表尾插入数据
bool SqTableInsertAtTail(SqTable* sq_table, ElemType e)
{
    if (sq_table->length == MAXSIZE)    // 顺序表已满
    {
        cout << "the sequence is full" << endl;
        return false;
    }
    sq_table->data[sq_table->length] = e;   // 赋值
    sq_table->length++; // 长度++
    return true;
}

// 向位置pos插入数据,pos是位序,对应下标为pos-1
bool SqTableInsertAtPos(SqTable* sq_table, int pos, ElemType e)
{
    if (pos < 1 || pos > MAXSIZE)   // 输入的位置超范围
    {
        cout << "the position is illegal" << endl;
        return false;
    }
    pos--;  // 获得下标
    for (int temp = sq_table->length - 1; temp >= pos; temp--)  // **从后往前移动数据**
    {
        sq_table->data[temp + 1] = sq_table->data[temp];
    }
    sq_table->data[pos] = e;    // 赋值
    sq_table->length++;
    return true;
}

// 删除位置pos的数据
bool SqTableDeleteAtPos(SqTable* sq_table, int pos, ElemType* e)
{
    if (pos < 1 || pos > MAXSIZE)   // 输入的位置超范围
    {
        cout << "the position is illegal" << endl;
        return false;
    }
    pos--;  // 获得下标
    *e = sq_table->data[pos];   // 取值
    for (int temp = pos; temp < sq_table->length; temp++)   // **从前往后移动数据**
    {
        sq_table->data[temp] = sq_table->data[temp + 1];
    }
    sq_table->length--;
    return true;
}

// 查找值为e的元素的位序
int SqTableFindE(SqTable sq_table, ElemType e)
{
    for (int temp = 0; temp < sq_table.length; temp++)  // 遍历数组
    {
        if (sq_table.data[temp] == e)
        {
            return (temp + 1);  // 获得位序
        }
    }
    cout << "the element is not find" << endl;
    return -1;
}

// 查找位序为pos的元素
bool SqTableGetValue(SqTable sq_table, ElemType* e, int pos)
{
    if (pos < 0 || pos >= sq_table.length)  // 位序超范围
    {
        cout << "the position is illegal" << endl;
        return false;
    }
    *e = sq_table.data[pos - 1];    // pos-1为下标
    return true;
}

// 顺序表输出
void SqTablePrint(SqTable sq_table)
{
    for (int temp = 0; temp < sq_table.length; temp++)  // 遍历数组输出
    {
        cout << sq_table.data[temp] << " ";
    }
    cout << endl;
}

int main()
{
    ElemType e = 0;
    int pos = 0;

    SqTable sq_table;
    SqTableInit(&sq_table);
    SqTableInitData(&sq_table);
    SqTablePrint(sq_table);

    cout << "Please cin the element that will be inserted" << endl;
    cin >> e;
    SqTableInsertAtTail(&sq_table, e);
    SqTablePrint(sq_table);
    cout << "Please cin the location of the element that will be inserted" << endl;
    cin >> pos >> e;
    SqTableInsertAtPos(&sq_table, pos, e);
    SqTablePrint(sq_table);

    cout << "Please cin the location of the element that will be deleted" << endl;
    cin >> pos;
    SqTableDeleteAtPos(&sq_table, pos, &e);
    cout << "the deleted element: " << e << endl;
    SqTablePrint(sq_table);

    cout << "Please cin the element that will be find" << endl;
    cin >> e;
    cout << "the element is at: " << SqTableFindE(sq_table, e) << endl;
    cout << "Please cin a location" << endl;
    cin >> pos;
    SqTableGetValue(sq_table, &e, pos);
    cout << "the element at location is: " << e << endl;

    return 0;
}

顺序表的动态分配

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

#define SIZE_INIT 2 // 初始化顺序表大小
#define CREASE_LEN 2    // 扩容时的增量

typedef int ElemType;

struct SqTable
{
    ElemType* data; // 可变动态数组
    int length; // 元素个数
    int size;   // 顺序表容量
};

// 顺序表初始化
bool SqTableInit(SqTable* sq_table)
{
    // 请求空间,malloc返回的是一个void*类型,因此要进行强制转换
    sq_table->data = (ElemType*)malloc(SIZE_INIT * (sizeof(ElemType)));
    if (sq_table->data == NULL) // 请求空间失败
    {
        return false;
    }
    sq_table->length = 0;   // 初始化元素个数
    sq_table->size = SIZE_INIT; // 初始化容量
    return true;
}

// 使用relloc进行扩容,使用relloc扩容,容量是在原空间上增加,不用转移数据
bool SqTableIncreaseByRelloc(SqTable* sq_table)
{
    sq_table->data = (ElemType*)realloc(sq_table->data, (sq_table->size + CREASE_LEN) * (sizeof(ElemType)));
    if (sq_table->data == NULL) // 请求空间失败
    {
        return false;
    }
    sq_table->size = sq_table->size + CREASE_LEN;
    return true;
}

// 使用malloc进行扩容,malloc会重新分配一片空间,因此需要转移数据
bool SqTableIncreaseByMalloc(SqTable* sq_table)
{
    ElemType* storage = sq_table->data; // 使用指针变量暂存原数组的首地址
    sq_table->data = (ElemType*)malloc((sq_table->size + CREASE_LEN) * (sizeof(ElemType)));
    if (sq_table->data == NULL) // 请求空间失败
    {
        return false;
    }
    for (int temp = 0; temp < sq_table->length; temp++) // 转移数据
    {
        sq_table->data[temp] = storage[temp];
    }
    sq_table->size = sq_table->size + CREASE_LEN;
    return true;
}

// 向顺序表尾插入数据
bool SqTableInsertAtTail(SqTable* sq_table, ElemType e)
{
    if (sq_table->length == sq_table->size) // 需要扩容
    {
        bool SqIncreaseResult = SqTableIncreaseByRelloc(sq_table);  // relloc尝试扩容
        if (!SqIncreaseResult)  // 扩容失败
        {
            cout << "the sequence is full, and capacity increase failt" << endl;
            return false;
        }
    }
    sq_table->data[sq_table->length] = e;   // 赋值
    sq_table->length++;
    return true;
}

// 向位置pos插入数据,pos是位序,对应下标为pos-1
bool SqTableInsertAtPos(SqTable* sq_table, int pos, ElemType e)
{
    if (sq_table->length == sq_table->size) // 扩容
    {
        bool SqIncreaseResult = SqTableIncreaseByMalloc(sq_table);  // malloc尝试扩容
        if (!SqIncreaseResult)  // 扩容失败
        {
            cout << "the sequence is full, and capacity increase failt" << endl;
            return false;
        }
    }
    pos--;  // 获得下标
    for (int temp = sq_table->length - 1; temp >= pos; temp--)  // **从后往前移动数据**
    {
        sq_table->data[temp + 1] = sq_table->data[temp];
    }
    sq_table->data[pos] = e;    // 赋值
    sq_table->length++;
    return true;
}

// 删除位序pos的元素
bool SqTableDeleteAtPos(SqTable* sq_table, int pos, ElemType* e)
{
    if (pos < 1 || pos > sq_table->length)  // 输入的位序超范围
    {
        cout << "the position is illegal" << endl;
        return false;
    }
    pos--;  // 获得下标
    *e = sq_table->data[pos];
    for (int temp = pos; temp < sq_table->length; temp++)   // **从左往右移动数据**
    {
        sq_table->data[temp] = sq_table->data[temp + 1];
    }
    sq_table->length--; // 元素个数更新
    return true;
}

// 查找位序pos的元素
bool SqTableGetValue(SqTable sq_table, ElemType* e, int pos)
{
    if (pos < 1 || pos > sq_table.length)  // 输入的位序超范围
    {
        cout << "the position is illegal" << endl;
        return false;
    }
    pos--;  // 获得下标
    *e = sq_table.data[pos];
    return true;
}

// 查找元素e
int SqTableFindE(SqTable sq_table, ElemType e)
{
    for (int temp = 0; temp < sq_table.length; temp++)  // 遍历指针数组
    {
        if (sq_table.data[temp] == e)
        {
            return (temp + 1);  // temp+1获得位序
        }
    }
    cout << "the element is not find" << endl;
    return -1;
}

// 数据初始化
bool SqTableInitData(SqTable* sq_table)
{
    cout << "Please cin the number of sequence element" << endl;
    int sequence_length = 0;
    cin >> sequence_length; // 输入初始化时顺序表中元素的个数
    cout << "Please cin the element of sequence" << endl;
    for (int temp = 0; temp < sequence_length; temp++)  // 输入顺序表元素
    {
        ElemType temp_in;
        cin >> temp_in;
        SqTableInsertAtTail(sq_table, temp_in); // 直接向表尾插入元素,时间复杂度O(1)
    }
    return true;
}

// 顺序表输出
void SqTablePrint(SqTable sq_table)
{
    for (int temp = 0; temp < sq_table.length; temp++)  // 遍历输出
    {
        cout << sq_table.data[temp] << " ";
    }
    cout << endl;
}

int main()
{
    ElemType e = 0;
    int pos = 0;

    SqTable sq_table;
    SqTableInit(&sq_table);
    SqTableInitData(&sq_table);
    SqTablePrint(sq_table);

    cout << "Please cin the location of the element that will be inserted" << endl;
    cin >> pos >> e;
    SqTableInsertAtPos(&sq_table, pos, e);
    SqTablePrint(sq_table);

    cout << "Please cin the location of the element that will be deleted" << endl;
    cin >> pos;
    SqTableDeleteAtPos(&sq_table, pos, &e);
    cout << "the deleted element: " << e << endl;
    SqTablePrint(sq_table);

    cout << "Please cin the element that will be find" << endl;
    cin >> e;
    cout << "the element is at: " << SqTableFindE(sq_table, e) << endl;
    cout << "Please cin a location" << endl;
    cin >> pos;
    SqTableGetValue(sq_table, &e, pos);
    cout << "the element at location is: " << e << endl;

    return 0;
}
posted @   木槐muhuai  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示