线性表(顺序表、链表、栈、队列、特殊数组)

        如下为本人自己总结整理的常考的数据结构伪代码(C语言),可能存在错误,欢迎批评指正。

目录

(一)顺序表:

        1.1顺序存储结构定义

        1.2两个顺序存储的有序线性表合并为一个新数组

        1.3两个长度分别为m、n,采用顺序存储的有序线性表合并为一个有序线性表,合并时将其中一个合并到另一个中

(二)链表

        2.1单链表存储结构定义

        2.2单链表就地逆置

        2.3不带头结点的有序链表合并

        2.4查找带头结点的单链表的倒数第k个结点-快慢指针应用

        2.5删除单链表的倒数第k个结点-快慢指针的应用

        2.6向带头结点的从小到大有序循环单链表中插入值x

        2.7向带头结点的从小到大有序循环双链表中插入值x

        2.8将带头结点的单链表分为奇数和偶数元素的两个表,除头结点外不得开辟新空间,元素相对顺序保持不变

(三)栈

        3.1链栈的存储结构定义

        3.2带头结点的链栈的入栈操作

        3.3不带头结点的链栈的入栈操作

(四)队列

        4.1用两个栈构造队列

        4.2借助栈将队列中的元素逆置

        4.3利用栈和队列判断字符序列是否为回文串

(五)特殊矩阵

        5.1三元组矩阵存储结构定义

        5.2构造三元组矩阵(仅供参考,基本不用)

(一)顺序表:

1.1顺序存储结构定义
//静态分配
#define MaxSize 100
typedef int ElemType;
typedef struct{
    ElemType data[MaxSize];
    int length;
}SqList;

//动态分配
#define InitSize 100
typedef int ElemType;
typedef struct{
    ElemType *data;
    int length;//当前长度
    int Maxsize;//最大长度
}SqList;
1.2两个顺序存储的有序线性表合并为一个新数组
bool Merge(SqList A,SqList B,SqList C){//从小到大排序
    if(A.length+B.length>C.MaxSize)return false;
    int i=0,j=0,k=0;
    while(i<A.length && j<B.length){
        if(A.data[i]<B.data[j])C.data[k++]=A.data[i++];
        else C.data[k++]=B.data[j++];
    }
    while(i<A.length)C.data[k++]=A.data[i++];
    while(j<B.length)C.data[k++]=B.data[j++];
    C.length=k;
    return ture;
}
1.3两个长度分别为m、n,采用顺序存储的有序线性表合并为一个有序线性表,合并时将其中一个合并到另一个中
void merge(SqList &L1,SqList &L2,int n){
    int i=0,j=0;
    while(i<L1.length&&j<n){
    if(L1.data[i]<=L2.data[j])i++;
    else{
        for(int k=L1.length;k>i;k--){//元素后移
            L1.data[k]=L1.data[k-1];
        }
        L1.data[i-1]=L2.data[j];
        i++;
        j++;
        L1.length++:
    }
}
    while(j<n){
        L1.data[i]=L2.data[j];
        i++;
        j++;
        L1.length++;
    }
}

(二)链表

2.1单链表存储结构定义
typedef struct LNode{
    ElemType e;
    struct LNode*next;
}LNode,*LinkList;
2.2单链表就地逆置
LinkList Reverse(LinkList &L){//带头结点
    LNode *p=L→next,*q;
    L→next=NULL;
    if(p!==NULL){
        q=p→next;
        p→next=L→next;
        L→next=p;//头插法
        p=q;
    }
    return L;
}
2.3不带头结点的有序链表合并
LNode* UnionLinkList(LinkList &head1,LinkList &head2){
    if(head1==NULL||head2==NULL){
    head1=head2;
    return head1;
    }
    LNode*head=(LNode*)malloc(sizeof(LNode));
    head→next=NULL;
    LNode*r=head;//r指向合并后的有序链表head的尾结点
    while(head1!=NULL&&head2!=NULL){
        if(head1→data<=head2→data){
            r→next=head1;
            head1=head1→next;
            r=r→next;
        }else{
            r→next=head2;
            head2=head2→next;
            r=r→next;
        }
    }
    r→next=NULL;
    if(head1!=NULL)r→next=head1;
    if(head2!=NULL)r→next=head2;
    head1=head→next;
    free(head);
    return head1;
}
2.4查找带头结点的单链表的倒数第k个结点-快慢指针应用
bool Search_k(LinkList &head,ElemType &x,int k){//此处强调链表用LinkList
    if(head→next==NULL||k<=0)return false;//链表为空或k值不合法
    LNode *fast=head,*slow=head;
    for(int i=0;i<k&&fast!=NULL;i++){//让fast指针领先slow k个位置
        fast=fast→next;
    }
    if(fast==NULL){
        print(“k值超过链表长度,不合法!”);
        return false;
    }
    while(fast→next!=NULL){//循环结束后fast指向了链表最后一个结点
        slow=slow→next;
        fast=fast→next;
    }
    x=slow→next→data;//slow指向了倒数第k+1个结点
    return ture;
}
2.5删除单链表的倒数第k个结点-快慢指针的应用

同上类似,在找到第k个结点位于slow→next位置后,执行slow→next=slow→next→next;

2.6向带头结点的从小到大有序循环单链表中插入值x
bool Insert(LinkList &L,int x){
    LNode*p=L;
    LNode*s=(LNode*)malloc(sizeof(LNode));
    if(s==NULL)return false;//内存已满
    s→data=x;
    while(p→next!=L&&p→next→data>=x){
        p=p→next;
    }
    s→next=p→next;//已包含L→next=L的情况
    p→next=s;
    if(p→next==L)r=s;
    return ture;
}
2.7向带头结点的从小到大有序循环双链表中插入值x
typedef struct DNode{
ElemType data;
    struct DNode*prior,*next;
}DNode,*DLinkList;

bool Insert(DLinkList &L,int x){
    DNode*p=L;
    DNode*s=(DNode*)malloc(sizeof(DNode));
    if(s==NULL)return false;//内存已满
        s→data=x;
    while(p→next!=L&&p→next→data>=x){
        p=p→next;
    }
    s→next=p→next;//已包含L→next=L、L→prior=L的情况;
    s→prior=p;
    p→next→prior=s;
    p→next=s;
    return ture;
}
2.8将带头结点的单链表分为奇数和偶数元素的两个表,除头结点外不得开辟新空间,元素相对顺序保持不变
bool CreatL(LinkList &L,LinkList &L1){//L为已知头结点--尾插法保证元素相对顺序保持不变
    if(L→next==NULL)return false;//链表为空
    L1=(LNode*)malloc(sizeof(LNode));//偶数元素链表的头结点
    if(L1==NULL)return false;//内存已满
    LNode*p=L,*q=L1;
    while(p→next!=NULL){
        if(p→next→data%2==0){//偶数元素存放在链表L1后
            q→next=p→next;
            q=q→next;
            q→next=NULL;
            p→next=p→next→next;
        }
        p=p→next;
    }
    return ture;
}

(三)栈

3.1链栈的存储结构定义
typedef struct LNode{
    ELemType data;
    struct LNode *next;
}LNode,*LStack;//栈顶指针为头结点S
3.2带头结点的链栈的入栈操作
bool Push(LStack &S,ElemType x){
    LNode *p=(LNode*)malloc(sizeof(LNode));
    if(p==NULL)return false;//内存已满
    p→data=x;
    p→next=S→next;//头插
    S→next=p;
    return ture;
}
3.3不带头结点的链栈的入栈操作
bool Push(LStack &S,ElemType x){
    LNode *p=(LNode*)malloc(sizeof(LNode));
    if(p==NULL)return false;//内存已满
    p→data=x;
    p→next=S;
    S=p;
    return ture;
}

(四)队列

4.1用两个栈构造队列

ps:用两个栈(未规定是顺序栈还是链栈)模拟队列的入队、出队、判空等基本操作

bool EnQueue(Stack &S1,Stack &S2,ElemType e){//入队
    if(!StackOverflow(S1)){//S1栈满
        Push(S1,e);
        return ture;
    }
    if(StackOverflow(S1)&&!isEmpty(S2)){//S1栈满,S2栈非空
        print(“队列已满!”);
        return false;
    }
    if(StackOverflow(S1)&&isEmpty(S2)){//S1栈满,S2栈为空
        while(!isEmpty(S1)){//S1全部出栈入栈到S2中
            Pop(S1,x);
            Push(S2,x);
        }
        Push(S1,e);
        return ture;
    }
}

bool DeQueue(Stack &S1,Stack &S2,ElemType &x){//出队
    if(!isEmpty(S2)){
        Pop(S2,x);
    }else if(isEmpty(S2)&&!isEmpty(S1)){
        while(!isEmpty(S1)){
            Pop(S1,x);
            Push(S2,x);
        }
        Pop(S2,x);
    }else if(isEmpty(S1){
        print(“队列为空!”);
        return false;
    }
    return ture;
}

bool isEmpty(Stack S1,Stack S2){
    if(isEmpty(S1)&&isEmpty(S2))return ture;
    return false;
}
4.2借助栈将队列中的元素逆置
bool ReverseQueue(Queue &Q,Stack S){
    while(!isEmpty(Q)){//队列元素出队后,入栈S
        x=DeQueue(Q);//参数无x则需返回x
        Push(S,x);
    }
    while(!isEmpty(S)){出栈后入队
        Pop(S,x);//参数有x的无需返回x
        EnQueue(Q,x);
    }
}
4.3利用栈和队列判断字符序列是否为回文串
//利用栈+队列判断字符序列
bool Judge(char ch[]){
    Stack S;
    Queue Q;
    char e1,e2;
    InitStack(S);
    InitQueue(Q);
    int i=0;//记录字符个数
    while(!ch[i]){
        Push(S,ch[i]);
        EnQueue(S,ch[i]);
        i++;
    }
    for(i;i>0;i--){
        Pop(S,e1);
        DeQueue(Q,e2)
        if(e1!=e2)return false;
    }
    return ture;
}
//判断一个数是否是回文数
bool Judge(int num){
    int s=num,x=0;
    while(s>0){
        x=x*10+s%10;
        s=s/10;
    }
    if(x==num)return ture;
    else return false;
}

(五)特殊矩阵

5.1三元组矩阵存储结构定义
#define SMAX 1000
typedef struct{
    int i,j;//存储非零元素的行列信息
    ElemType e;//非零元素信息
}Triple;//定义三元组类型
typedef struct{
    int mu,nu,tu;//存储三元组的行数、列数、非零元素个数
    Triple data[SMAX];//三元组表
}TSMatrix;
5.2构造三元组矩阵(仅供参考,基本不用)
void CreateTSMatrix(int[][] A,int r,int c,TSMatrix &B){//给定稀疏矩阵A及其行数、列数,构造三元组B
    int k=1;
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
            if(A[i][j]!=0){
                B→data[k].i=i;
                B→data[k].j=j;
                B→data[k].e=A[i][j];
                k++;
            }
        }
    }
    B→mu=r;//矩阵的行数
    B→nu=c;//矩阵的列数
    B→tu=k-1;//矩阵的非零元素个数
}

void TransposeSMatrix(TSMatrix *M, TSMatrix *T) {
    T->mu = M->nu;
    T->nu = M->mu;
    T->tu = M->tu;
    if(T->tu) {
        int q = 1;
        for(int col=0; col<M->nu; col++)
            for(int p=1; p<=M->tu; p++)
                if(M->data[p].j==col) {
                    T->data[q].i = M->data[p].j;
                    T->data[q].j = M->data[p].i;
                    T->data[q].e = M->data[p].e;
                    q++;
                }
            }
        }
    }
}

void PrintTSMatrix(TSMatrix *T) {
    printf("the triple matrix is: /n");
    for(int i=0; i<T->tu; i++) {
        printf("%d, %d, %d/n", T->data[i+1].i, T->data[i+1].j, T->data[i+1].e);
    }
}

int main() {
    int Matrix[][7] = {​{0, 12, 9, 0, 0, 0, 0},
       {0, 0, 0, 0, 0, 0, 0},
       {-3, 0, 0, 0, 0, 14, 0},
       {0, 0, 24, 0, 0, 0, 0},
       {0, 18, 0, 0, 0, 0, 0},
       {15, 0, 0, -7, 0, 0, 0}};
    TSMatrix M;
    TSMatrix T;
    CreateTSMatrix(&M, Matrix, 7, 6, 8);
    PrintTSMatrix(&M);
    TransposeSMatrix(&M, &T);
    PrintTSMatrix(&T);
}
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值