顺序表的构造及功能

定义

顺序表是一种随机存储都结构,其特点是表中的元素的逻辑顺序与物理顺序相同。

假设线性表L存储起始位置为L(A),sizeof(ElemType)是每个数据元素所占的存储空间的大小,则线性表L所对应的顺序存储如下图。

顺序表的优缺点
优点:
随机存储表中的任意元素,其存储位置可以用一个简单、直观的公式来表示。
存储密度高,每个结点只存储数据元素。

缺点:
在做插入或删除元素时,需要移动大量元素。
操作相对复杂,必然导致空间的浪费。

静态顺序表的构建

在静态分配时,由于数组的大小和空间事先已经固定好,一旦空间占满,再加入新的数据就会产生溢出,进而导致进程崩溃。

#define MaxSize 100           //顺序表可能达到的最大长度
typedef int ElemType;
typedef struct{
    ElemType data[MaxSize];  //顺序表的元素
    int length;              //当前的长度
}List;                       //顺序表的类型定义

注意:线性表中元素的位置是从1开始的,而数组中的元素的下标是从0开始的。

动态顺表的构建

#define MaxSize 100  //顺序表可能达到的最大长度
typedef int ElemType;
typedef struct{
    ElemType* data;  //存储空间的基址
    int length;      //当前的长度
}List;               //顺序表的结构类型为List

C的初始动态分配语句

list.data = (ElemType*)malloc(sizeof(ElemType)*MaxSize);  //动态开辟空间 (c语言)

C++的初始动态分配语句

list.data = new ElemType[MaxSize];  //动态开辟空间 (c++)

注意:动态分配并不是链式存储,它同样属于顺序存储结构,,物理结构没有变化,依然是随机存储方式,只是分配的空间大小可以在运行时动态决定。

动态顺序表的常见操作

插入

插入新元素的图解

void Insert(List *list, int index, int value){  //插入(在第index位置插入value)
    if (index < 1 || index > list->length + 1){  //判断范围是否有效
        printf("插入失败(位置输入错误)!\n");
        return;
    }
    if (list->length >= MaxSize){   //空间已满,无法插入
        printf("插入失败(顺序表已满)!\n");
        return;
    }
    for (int i = list->length; i >= index; i--){  //将第index个元素及之后的元素后移
        list->data[i] = list->data[i - 1];
    }
    list->data[index - 1] = value;  //将位置index放入value
    list->length++;  //线性表长度加一
    printf("插入成功!\n");
    return;
}
线性表插入算法的平均时间复杂度为O(N)。

取值

根据下标来查找元素

void GetElem(List list, int index){  //取值(用下标找元素)
    if (index >= 0 && index < list.length){
        printf("要查找的第%d个元素是:%d\n", index, list.data[index - 1]);
    }
    else{
        printf("输入的值有误!!\n");
    }
}

查找

根据所给的元素来遍历顺序表来寻找

void LocateElem(List list, int value){ //查找(用值找下标)
    for (int i = 0; i < list.length; i++){
        if (value == list.data[i]){
            printf("%d是本表中的第%d元素\n", value, i + 1);
            return;
        }
    }
    printf("找不到该元素\n");
    return;
}
线性表按值查找算法的平均时间复杂度为O(N)。

删除

删除元素的图解

void Delete(List *list, int index){ //删除(删除指定的第几个元素)
    if (index < 1 || index > list->length) {  //判断index的范围是否有效
        printf("删除失败(输入的数值有误)!\n");
        return;
    }
    for (int i = index - 1; i < list->length - 1; i++){  //将第index个位置后的元素前移
        list->data[i] = list->data[i + 1];
    }
    list->length--;  //线性表长度减一
    printf("删除成功!\n");
    return;
}
线性表删除算法的平均时间复杂度为O(N)。

销毁
void Clear(List *list){  //销毁
    list->length = 0;   //将顺序表的长度设为0
    free(list->data);   //释放malloc申请的空间
    printf("顺序表已销毁!\n");
}

划分

已第一个元素为界,比它小的元素放在它的前面,比它大的元素放在它的后面

void ListSort(List *list){  //划分(已第一个元素为界,前面比它小,后面比它大)
    int i = 0, j = 0;
    int temp, k;
    temp = list->data[0];
    for (i = 1; i < list->length; i++){
        if (temp > list->data[i]){
            k = list->data[i];
            for (j = i; j > 0; j--){
                list->data[j] = list->data[j - 1];
            }
            list->data[0] = k;
        }
    }
    printf("划分成功!\n");
    return;
}

单值化

单值化类似与去掉顺序表中重复的元素

void DeleteSame(List *list){  //单值化(去掉重复的元素)
    int i = 0;
    while (i < list->length){
        for (int j = i + 1; j <= list->length; j++)
        while (list->data[i] == list->data[j]){
            for (int k = j; k <= list->length; k++)
                list->data[k] = list->data[k + 1];
            list->length--;
        }
        i++;
    }
    printf("单值化完成!\n");
    return;
}

源码

SeqList.h
#include <stdio.h>
#include <windows.h>
#include <malloc.h>

#define MaxSize 100
typedef int ElemType;
typedef struct{
    ElemType* data;  //动态顺序表
    int length;
}List;

void menu();
void PutList(List list);
void GetElem(List list, int index);
void LocateElem(List list, int value);
void Insert(List *list, int index, int value);
void Delete(List *list, int index);
void DeleteSame(List *list);
void ListSort(List *list);
void Clear(List *list);

SeqList.c
#include "SeqList.h"

void PutList(List list){  //输出(遍历线性表)
    for (int i = 0; i < list.length; i++){
        printf("%d ", list.data[i]);
    }
    printf("\n");
}

void GetElem(List list, int index){  //取值(用下标找元素)
    if (index >= 0 && index < list.length){
        printf("要查找的第%d个元素是:%d\n", index, list.data[index - 1]);
    }
    else{
        printf("输入的值有误!!\n");
    }
}

void LocateElem(List list, int value){ //查找(用值找下标)
    for (int i = 0; i < list.length; i++){
        if (value == list.data[i]){
            printf("%d是本表中的第%d元素\n", value, i + 1);
            return;
        }
    }
    printf("找不到该元素\n");
    return;
}

void Insert(List *list, int index, int value){  //插入(在第index位置插入value)
    if (index < 1 || index > list->length + 1){
        printf("插入失败(位置输入错误)!\n");
        return;
    }
    if (list->length >= MaxSize){
        printf("插入失败(顺序表已满)!\n");
        return;
    }
    for (int i = list->length; i >= index; i--){
        list->data[i] = list->data[i - 1];
    }
    list->data[index - 1] = value;
    list->length++;
    printf("插入成功!\n");
    return;
}

void Delete(List *list, int index){ //删除(删除指定的第几个元素)
    if (index < 1 || index > list->length) {
        printf("删除失败(输入的数值有误)!\n");
        return;
    }
    for (int i = index - 1; i < list->length - 1; i++){
        list->data[i] = list->data[i + 1];
    }
    list->length--;
    printf("删除成功!\n");
    return;
}

void DeleteSame(List *list){  //单值化(去掉重复的元素)
    int i = 0;
    while (i < list->length){
        for (int j = i + 1; j <= list->length; j++)
        while (list->data[i] == list->data[j]){
            for (int k = j; k <= list->length; k++)
                list->data[k] = list->data[k + 1];
            list->length--;
        }
        i++;
    }
    printf("单值化完成!\n");
    return;
}

void ListSort(List *list){  //划分(已第一个元素为界,前面比它小,后面比它大)
    int i = 0, j = 0;
    int temp, k;
    temp = list->data[0];
    for (i = 1; i < list->length; i++){
        if (temp > list->data[i]){
            k = list->data[i];
            for (j = i; j > 0; j--){
                list->data[j] = list->data[j - 1];
            }
            list->data[0] = k;
        }
    }
    printf("划分成功!\n");
    return;

}

void Clear(List *list){  //销毁
    list->length = 0;
    free(list->data);
    printf("顺序表已销毁!\n");
}

void menu(){  //菜单
    printf("顺序表操作:< P-输出  G-取值  L-查找  I-插入  D-删除  S-单值化  F-划分  X-销毁  Q-退出 >\n");
}

Test.c
#include "SeqList.h"

int main(){
    List list;
    list.data = (ElemType*)malloc(sizeof(ElemType)*MaxSize);  //动态开辟空间 (c语言)
    //list.data = new ElemType[MaxSize];  //动态开辟空间 (c++)

    printf("线性表中元素的个数:");
    int n = 0;
    scanf("%d", &n);
    list.length = n;
    printf("请输入元素:");
    for (int i = 0; i < n; i++){
        int t = 0;

        //cin >> list.data[i]; //c++输入
        scanf("%d", &t);
        list.data[i] = t;
    } 

    while (1){
        menu();
        char key;
        //cin >> key; //c++输入
        int t = 0;
        getchar();  //释放scanf读取的\n
        scanf("%c", &key);

        switch (key){
        case 'P':
            PutList(list); //输出
            break;

        case 'G':
            printf("要查找第几个元素:");
            scanf("%d", &t);
            GetElem(list,t);  //取值
            break;

        case 'L':
            printf("要查找元素的值为:");
            scanf("%d", &t);
            LocateElem(list,t); //查找
            break;

        case 'I':
            printf("输入要插入的位置和数值:");
            int index, value;
            scanf("%d %d", &index,&value);
            Insert(&list, index, value);  //插入
            break;

        case 'D':
            printf("输入要删除第几个元素:");
            scanf("%d", &t);
            Delete(&list, t);  //删除
            break;

        case 'S':
            DeleteSame(&list); //单值化
            break;

        case 'F':
            ListSort(&list);  //划分
            break;

        case 'X':
            Clear(&list);  //销毁
            break;

        case 'Q':
            exit(0);  //退出
            break;
        }
    }
    system("pause");
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的顺序表的定义和实现: ```C++ #include <iostream> using namespace std; const int MAX_SIZE = 100; // 顺序表的最大长度 class SeqList { private: int data[MAX_SIZE]; // 存储数据的数组 int length; // 当前顺序表的长度 public: SeqList() { // 构造函数,初始化长度为0 length = 0; } // 插入元素函数 bool insert(int index, int value) { if (length == MAX_SIZE) { // 判断顺序表是否已满 return false; } if (index < 0 || index > length) { // 判断插入位置是否合法 return false; } for (int i = length; i > index; i--) { // 将插入位置之后的元素依次向后移动 data[i] = data[i - 1]; } data[index] = value; // 在插入位置处插入新元素 length++; // 长度加1 return true; } // 删除元素函数 bool remove(int index) { if (index < 0 || index >= length) { // 判断删除位置是否合法 return false; } for (int i = index; i < length - 1; i++) { // 将删除位置之后的元素依次向前移动 data[i] = data[i + 1]; } length--; // 长度减1 return true; } // 获取元素函数 bool get(int index, int& value) { if (index < 0 || index >= length) { // 判断获取位置是否合法 return false; } value = data[index]; // 将获取位置处的元素值赋给value return true; } // 修改元素函数 bool set(int index, int value) { if (index < 0 || index >= length) { // 判断修改位置是否合法 return false; } data[index] = value; // 将修改位置处的元素值修改为value return true; } // 获取顺序表长度函数 int getLength() { return length; } }; int main() { SeqList list; list.insert(0, 1); list.insert(1, 2); list.insert(2, 3); cout << "Length: " << list.getLength() << endl; int value; list.get(1, value); cout << "Value at index 1: " << value << endl; list.set(1, 4); list.get(1, value); cout << "Value at index 1 after set: " << value << endl; list.remove(2); cout << "Length after remove: " << list.getLength() << endl; return 0; } ``` 这个顺序表实现了插入、删除、获取、修改元素以及获取顺序表长度的功能。你可以根据自己的需求进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我会一直在的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值