线性表(C++实现)

线性表的定义与基本操作

定义

具有相同数据类型的n个数据元素的有限序列,n是表长,当n为0的时候线性表是一个空表。如果用L命名线性表,那么其一般表示为
L = ( a 1 , a 2 , . . . , a i , a i + 1 , . . . , a n ) L=(a_1,a_2, ...,a_i,a_{i+1},...,an) L=(a1a2...aiai+1...an)
式中, a 1 a_1 a1是唯一的"第一个"数据元素,称为表头元素,而 a n a_n an是唯一的"最后一个元素",称为表尾元素。

逻辑特性:除了第一个元素外,每个元素都有且只有一个直接前驱,除了最后一个元素外,每个元素都有且只有一个直接后继。

特点:

  • 表中元素个数有限
  • 表中元素具有逻辑上的顺序性,表中元素具有其先后次序。
  • 表中元素都是数据元素,每个元素都是单个元素
  • 表中元素的数据类型都相同,这意味着每个元素占有相同大小的存储空间
  • 表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟表示什么内容

**注意:线性表是一个逻辑结构,表示元素之间一对一的相邻关系。顺序表和链表指的是存储结构,两者之间没有任何关系,属于不同层面的问题。

线性表需要满足的基本操作(需要完成的接口)

  1. InitList(&L); 初始化表,构造一个空的线性表
  2. Length(L); 求表长。返回线性表L的长度,即L中元素的个数
  3. LocateElem(L,e); 按值查找操作。在表L中查找具有给定关键字值的元素
  4. GetElem(L,i); 按位查找操作,获取表L中第i个位置的元素
  5. ListInsert(&L, i, e); 插入操作,在表L中的第i个位置插入指定元素e
  6. ListDelete(&L, i, &e); 删除操作,删除表L中第i个位置的元素,并用e返回删除元素的值
  7. PrintList(L); 输出操作,按前后顺序输出线性表L的所有元素值
  8. Empty(L); 判空操作。如果L为空表,就返回true,否则返回false
  9. Destroy(&L); 销毁操作,销毁线性表,并释放线性表L所占用的内存空间

***注意:***①基本操作的实现取决于采用哪种存储结构(顺序表或是链表),存储结构不同,实现的算法也不一样。②"&"表示C++语言中的引用调用,在C语言中采用指针也可达到同样的效果。

顺序表(数组)实现
  1. DeletSmallest(&L); 从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除元素的值。空出的位置由最后一个元素填补,如果顺序表为空,则显示出错信息并推出运行
  2. Turn(&L); 设计一个高效的算法,将顺序表L的说有元素逆置,要求算法的空间复杂度为O(1)
  3. DeleteX(&L,x); 对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素
  4. inXAndY(&L,x,y); 从顺序表中删除其值在给定值s与t之间(包含s和t,要求s<t)的所有元素,若s或t不合理或顺序表为空,则显示出错信息并退出运行
  5. Unique(&L); 从有序顺序表中删除所有其值重复的元素,使表中所有的元素的值都不一样
  6. Merge(&L,&R); 将两个有序数组合并为一个新的有序顺序表,并由函数返回结果顺序表
  7. TurnInArray(&L,m); 已知一维数组A[m+n]中依次存放两个线性表, ( a 1 , a 2 , . . . , a m ) (a_1,a_2,...,a_m) (a1,a2,...,am) ( b 1 , b 2 , . . . , b n ) (b_1,b_2,...,b_n) (b1,b2,...,bn)。编写一个函数,将数组中两个顺序表的位置互换,即将 ( b 1 , b 2 , . . . , b n ) (b_1,b_2,...,b_n) (b1,b2,...,bn)放在 ( a 1 , a 2 , . . . , a m ) (a_1,a_2,...,a_m) (a1,a2,...,am)前面。
  8. SearchInDouble(&L,x); 线性表 ( a 1 , a 2 , a 3 , . . . , a n ) (a_1,a_2,a_3,...,a_n) (a1,a2,a3,...,an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找值为x的元素,若找到,则将其于后继元素位置相交换,若找不到,则将其插入表中并使表中元素仍递增有序
#include <iostream>
#include <cstring>

using namespace  std;

typedef struct {
    int * data;
    int MaxSize , length;
}SqList;

void Expand(SqList &L, int ex){
    int * p = L.data;
    L.data = new int [L.length+ex];
    for(int i = 0 ; i<L.length ; i++){
        p[i] = L.data[i];
    }
    delete[]p;
    cout<<"complete"<<endl;
}

void InitList( SqList &L , int initSize){
    L.data = new int [initSize];
    L.MaxSize = initSize;
    L.length = 0;
}

void Length(SqList L){
    cout<<L.length<<endl;
}

void LocateElem(SqList L, int e){
    for(int i = 0 ; i<L.length ; i++){
        if (L.data[i]==e) {
            cout << i;
            return;
        }
    }
    cout<<"not found"<<endl;
}

void GetElem(SqList L, int i ){
    if (i<1||i>L.length){
        cout<<"超出界限"<<endl;
        return;
    }
    cout<<L.data[i-1]<<endl;
}

void ListInsert(SqList &L, int i , int e){
    if(i<1||i>L.length+1){
        cout<<"超出界限"<<endl;
        return;
    }
    if(L.length>=L.MaxSize){
        Expand(L,5);
    }
    for(int j = L.length ; j>=i ; j--){
        L.data[j] = L.data[j-1];
    }
    L.data[i-1] = e;
    L.length++;
    cout<<"complete"<<endl;
}

bool Empty (SqList L){
    if (L.length==0){
        return true;
    }
    return false;
}

void ListDelete(SqList &L , int i , int &e){
    if(Empty(L)){
        cout<<"顺序表为空"<<endl;
        return;
    }
    e = L.data[i-1];
    for(int j = i ; j<=L.length ; j++){
        L.data[j-1] = L.data[j];
    }
    L.length--;
}

void PrintList(SqList L){
    for (int i = 0 ; i<L.length ; i++){
        cout<<L.data[i]<<" ";
    }
    cout<<endl;
}

void Destroy (SqList &L){
    delete []L.data;
    L.length=0;
    L.MaxSize=0;
    cout<<"complete"<<endl;
}

void DeleteSmallest(SqList &L){
    if(Empty(L)){
        cout<<"SqList is NULL!"<<endl;
        return;
    }
    int a = L.data[0];
    int id = 0;
    int *pid = &id;
    for (int i = 0; i < L.length; ++i) {
        if (a>L.data[i]){
            *pid = i;
            a = L.data[i];
        }
    }
    L.data[id] = L.data[L.length-1];
    L.length--;
    cout<<a<<"delete"<<endl;
}

void Turn (SqList &L){
    if (Empty(L)){
        cout<<"SqList is NULL!"<<endl;
        return;
    }
    int i = 0 ;
    int j = L.length-1;
    while(i<j){
        swap(L.data[i],L.data[j]);
        i++;
        j--;
    }
}

void DeleteX(SqList &L, int x){
    if (Empty(L)){
        cout<<"SqList is NULL!"<<endl;
        return;
    }
    int k = 0;
    int *pk = &k;
    for(int i = 0 ; i<L.length ; i++){
        if (L.data[i]==x){
            *pk+=1;
        }
        else{
            L.data[i-*pk] = L.data[i];
        }
    }
    L.length = L.length-*pk;
}

void inXAndY(SqList &L, int x , int y){
    if(Empty(L)){
        cout<<"SqList is Empty!"<<endl;
        return;
    }
    if(x>y){
        swap(x,y);
    }
    int k = 0 ;
    int *pk = &k;
    for(int i = 0 ; i<L.length; i++){
        if (L.data[i]>=x&&L.data[i]<=y){
            *pk+=1;
        }
        else{
            L.data[i-k] = L.data[i];
        }
    }
    L.length = L.length-*pk;
}

void Unique(SqList &L){
    int *p = L.data;
    L.data =  new int [L.MaxSize];
    bool *flag = new bool [100];
    int j = 0;
    memset(flag,false,10);
    for(int i = 0 ; i<L.length ; i++){
        if (!flag[p[i]]){
            L.data[j] = p[i];
            flag[p[i]]= true;
            j++;
        }
    }
    L.length = j;
    delete[]p;
}

void Merge(SqList &L , SqList &R){
    while (L.MaxSize<R.length){
        Expand(L,R.length);
    }
    int *p = L.data;
    int i = 0 , j = 0 , id = 0;
    while(i<L.length&&j<R.length){
        if (p[i]<=R.data[j]){
            L.data[id] = p[i];
            i++;
        } else{
            L.data[id] = R.data[j];
            j++;
        }
        id++;
    }
    if (i<L.length){
        for (;  i<L.length ; i++,id++) {
            L.data[id]= p[i];
        }
    }
    if(j<R.length){
        for (;  j<R.length ; j++,id++) {
            L.data[id] = R.data[j];
        }
    }
    L.length = R.length+L.length;
}

void TurnInArray(SqList &L,int m ){
    int *p = L.data;
    L.data = new int [L.MaxSize];
    int j = 0;
    for (int i = m ; i <L.length ; ++i,j++) {
        L.data[j] = p[i];
    }
    for(int i = 0 ; i<m ; i++,j++){
        L.data[j] = p[i];
    }
}

void SearchInDouble (SqList &L, int x){
    int left = 0;
    int right = L.length-1;
    int m  ;
    while(left<right){
        m = (left+right)/2;
        if (L.data[m]<x){
            left = m+1;
        }
        else if(L.data[m]>x){
            right = m-1;
        } else{
            swap(L.data[m],L.data[m+1]);
            return;
        }
    }
    ListInsert(L,left+2,x);
}

int main() {
    SqList L ;
    int initSize = 10;
    int show = 0;
    InitList(L,initSize);
}
链表(指针)实现
//
// Created by PrimeChuJiang on 2022/11/12.
//
#include <iostream>

using namespace std;

typedef struct LNode{
    int data;
    struct LNode *ptr;
}LNode , *LinkList;

bool InitList(LinkList & L){
//    LNode a ;
    L = new LNode ;
    if (L== nullptr)return false;
    L->ptr = nullptr;
    return true;
}

int Length(LinkList L){
    LNode * p = L;
    int i = 0 ;
    for ( ; p->ptr != nullptr ; p = p->ptr) {
        i++;
    }
    return i;
}

LNode* LocateElem(LinkList L, int e){
    LNode *p = L;
    while(p->ptr != nullptr){
        if (p->data==e){
            return p;
        }
        else{ continue;}
    }
    return nullptr;
}

LNode * GetElem(LinkList L , int i){
    LNode *p = L->ptr;
    if (i==0){return L;}
    if (i<0)return nullptr;
    for (int j = 1; j < i && p ; ++j) {
        p = p->ptr;
    }
    return p;
}

void ListInsert (LinkList &L , int i , int e){
    LNode *p = GetElem(L , i);
    auto s = new LNode ;
    s->data = p->data;
    s->ptr = p->ptr;
    p->ptr = s;
    p->data = e;
}

bool ListDelete(LinkList &L , int i , int &e){
    LNode *p = GetElem(L,i-1);
    LNode *d = p->ptr;
    p->ptr = d->ptr;
    delete d;
    return true;
}

void PrintList(LinkList L){
//    LNode *p = L;
    for (LNode *p= L->ptr;  p!= nullptr ; p=p->ptr) {
        cout << p->data;
    }
}

bool Empty(LinkList L){
    return L->ptr == nullptr;
}

void DestroyList(LinkList &L){
    if (!L->ptr){
        delete L;
        return;
    }
    LNode *p = L->ptr;
    LNode *d = L;
    while(p->ptr){
        delete d;
        d = p;
        p = p->ptr;
    }
    delete d;
    delete p;
}

LinkList List_HeadInsert(LinkList &L, int e){
    auto *p = new LNode ;
    p->data = e;
    p->ptr = L->ptr;
    L->ptr = p;
    return L;
}

LinkList List_TailInsert(LinkList &L, int e){
    auto *p = new LNode ;
    for(;p->ptr!= nullptr;p=p->ptr){}
    auto *s = new LNode ;
    s->data = e;
    p->ptr = s;
    s->ptr = nullptr;
    return L;
}

int main(){
    LinkList L ;
    InitList(L);
    cout <<"a"<<endl;

}
  • 17
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

楚江_wog1st

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

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

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

打赏作者

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

抵扣说明:

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

余额充值