数据结构--线性表

·  阅读 336

学习视频:来自于天勤考研 本文主要代码是使用的c++

1.逻辑结构

线性表是具有相同特性数据元素的==有限==序列。 相同特性:把同一类事物归类,方便批量处理。 有限:表中元素个数为n,n有限大,n可以为0。 序列:表中元素排成一列,体现了一对一的逻辑特性(每个元素有则仅有一个前驱和一个后继)。 在这里插入图片描述

2.存储结构

存储结构分为顺序存储结构链式存储结构

1.顺序存储和链式存储的区别:

性能具体功能顺序存储链式存储
空间性能存储分配一次性分配动态分配(优)
空间性能存储密度
(下面会有解释)
=1(优)<1
时间性能查找O(n/2)O(n/2)
时间性能读运算O(1)(优)O((n+1)/2)
最好情况为1,最坏情况为n
时间性能插入运算
(性能主要指
需要移动元素个数)
O(n/2)最好
最好情况为0,最坏情况为n
O(1),更优
时间性能删除运算O((n-1)/2)
最好情况为0,最坏情况为n-1
O(1),更优

结论: 从表整体来看,一般顺序表存储空间利用率低于链表。 从单个存储单元来看,实训存储空间利用率高于链表。

2.存储密度

存储密度=结点值域类所占的存储量/结点结构所占的存储总量。 顺序存储:只有数据,没有其他东西,所以数据所占的存储密度为1在这里插入图片描述 链式存储:除了数据,还有结点,所以数据所占的存储密度小于1。 在这里插入图片描述 ==关于为什么存储密度越小它就更优呢==? 因为顺序存储的存储密度为1,所以相同的内存,顺序存储存储的数据比链式存储多,所以顺序存储更优。

3.链式存储结构

1.单链表

结点类型定义: 在这里插入图片描述

带头结点(比较好用): 在这里插入图片描述

不带头结点(缺点,当链表为空时,需要重新写一部分代码): 在这里插入图片描述

2.双链表

结点类型定义: 在这里插入图片描述 带头结点: 在这里插入图片描述 不带头结点: 在这里插入图片描述

3.循环链表

带头结点的单循环链表和循环链表: 在这里插入图片描述 不带头结点的单循环链表和双循环链表: 在这里插入图片描述

4.静态链表

结点类型定义: 在这里插入图片描述 特点:一次性分配所以内存在这里插入图片描述

4.线性表的代码实现

1.顺序存储结构

顺序存储结构我们比较常见,所以实现起来还是比较熟悉的。

1.建表

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100

//建表
int createList(int A[],int &length){
    if(length>maxSize)
        return 0;
    for(int i=0;i<length;++i)
        cin>>A[i];
    return 1;
}
int main(){
    int A[maxSize];
    int length;
    cin>>length;
    createList(A,length);
    for(int i=0;i<length;i++){
        cout<<A[i]<<" ";
    }
    return 0;
}
复制代码

效果: 在这里插入图片描述

2.转置

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100

int createList(int A[],int &length){
    if(length>maxSize)
        return 0;
    for(int i=0;i<length;++i)
        cin>>A[i];
    return 1;
}

//转置代码
void Transpose(int a[],int length)
{
    int temp;
    for(int i=0,j=length-1;i<j;i++,j--){
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}
int main(){
    int A[maxSize];
    int length;
    cin>>length;
    createList(A,length);
    for(int i=0;i<length;i++){
        cout<<A[i]<<" ";
    }
    cout<<endl;
    
    Transpose(A,length);
    for(int i=0;i<length;i++){
        cout<<A[i]<<" ";
    }
    return 0;
}
复制代码

结果: 在这里插入图片描述

3.求最值

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100

int createList(int A[],int &length){
    if(length>maxSize)
        return 0;
    for(int i=0;i<length;++i)
        cin>>A[i];
    return 1;
}

//求最值
int maxData(int a[],int length){
    int max=a[0];
    int maxIdx=0;
    for(int i=0;i<length;++i){
        if(max<a[i]){
            max=a[i];
            maxIdx=i;
        }
    }
    return max;
}

int main(){
    int A[maxSize];
    int length;
    cin>>length;
    createList(A,length);
    cout<<maxData(A,length);
    return 0;
}
复制代码

4.划分

主要功能是:首先确定第一个数为划分点,然后通过i,j指向第一个元素和最后一个元素来比较,实现划分点前的数值一定小于它,划分点后的数一定大于它

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100

int createList(int A[],int &length){
    if(length>maxSize)
        return 0;
    for(int i=0;i<length;++i)
        cin>>A[i];
    return 1;
}

int maxData(int a[],int length){
    int max=a[0];
    int maxIdx=0;
    for(int i=0;i<length;++i){
        if(max<a[i]){
            max=a[i];
            maxIdx=i;
        }
    }
    return max;
}

void partition(int arr[],int n){
    int temp;
    int i=0,j=n-1;
    temp=arr[i];
    while(i<j)
    {
        while(i<j&&arr[j]>=temp)
            --j;
        if(i<j)
        {
            arr[i]=arr[j];
            ++i;
        }
        while(i<j&&arr[i]<temp)
            ++i;
        if(i<j)
        {
            arr[j]=arr[i];
            --j;
        }
        arr[i]=temp;
    }
}

int main(){
    int A[maxSize];
    int length;
    cin>>length;
    createList(A,length);
    partition(A,length);
    for(int i=0;i<length;i++)
        cout<<A[i]<<" ";
    cout<<endl;
    return 0;
}
复制代码

5.归并

主要功能:将两个数组按照大小排序放入同一个数组在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100

int createList(int A[],int &length){
    if(length>maxSize)
        return 0;
    for(int i=0;i<length;++i)
        cin>>A[i];
    return 1;
}

//归并
void mergearray(int a[],int m,int b[],int n,int c[])
{
    int i=0,j=0;
    int k=0;
    while(i<m&&j<n)
    {
        if(a[i]<b[j])
            c[k++]=a[i++];
        else
            c[k++]=b[j++];
    }

    while(i<m)
        c[k++]=a[i++];
    
    while(j<n)
        c[k++]=b[j++];
}

int main(){
    int A[maxSize];
    int B[maxSize];
    int C[maxSize];
    int length,length1;
    cin>>length;
    createList(A,length);
    cin>>length1;
    createList(B,length1);
    mergearray(A,length,B,length1,C);
    for(int i=0;i<length+length1;i++){
        cout<<C[i]<<" ";
    }
    cout<<endl;
    return 0;
}
复制代码

在这里插入图片描述

2.链式存储结构

1.建表

如果你是使用c语言的话,需要用 p=(LNode*)malloc(sizeof(LNode));这种形式来申请内存,但是如果你是用于c++的话,当然你也可以使用c语言的方法来申请内存,但是你可以使用p=new LNode();这种方法来申请内存,使用起来更简单方便,其中LNode()为你定义的结构体名字,和java有点相似。

如果你是其他类型的数据,把int类型改为你需要的类型就行了。

尾插法

#include <bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;

//尾插法
void createLinkListR(LNode *&head){
    head->next=NULL;
    LNode *p=NULL,*r=head;
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        p=new LNode();
        p->next=NULL;
        cin>>p->data;
        //这里主要针对于单链表
        p->next=r->next;
        r->next=p;
        r=p;
    }
}
int main(){
    LNode *head=new LNode();
    createLinkListR(head);
    for(LNode *r=head;r->next!=NULL;r=r->next){
         cout<<r->next->data<<" ";
    }
    return 0;
}
复制代码

效果: 在这里插入图片描述 头插法

#include<bits/stdc++.h>
using namespace std;

typedef struct LNode{
    int data;
    struct LNode *next;
}LNode;

void createLinkListH(LNode *&head){
    head->next=NULL;
    LNode *p=NULL;
    int n;
    cin>>n;
    for(int i=0;i<n;++i)
    {
        p=new LNode();
        p->next=NULL;
        cin>>p->data;
        p->next=head->next;
        head->next=p;
    }
}

int main(){
    LNode *head=new LNode();
    createLinkListH(head);
    for(LNode *r=head;r->next!=NULL;r=r->next){
         cout<<r->next->data<<" ";
    }
    return 0;
}
复制代码

可以从下面效果看出我们存储的数据与我们输入的数据的相反的。 效果: 在这里插入图片描述

2.转置

#include <bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;

//尾插法
void createLinkListR(LNode *&head,LNode *&r){
    head->next=NULL;
    LNode *p=NULL;
    r=head;
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        p=new LNode();
        p->next=NULL;
        cin>>p->data;
        p->next=r->next;
        r->next=p;
        r=p;
    }
}
//转置代码
void Transpose(LNode *&p,LNode *&q){
    LNode *t=NULL;
    while(p->next!=q){
        t=p->next;
        p->next=t->next;
        t->next=q->next;
        q->next=t;
    }
}
int main(){
    LNode *head=new LNode();
    LNode *r;
    createLinkListR(head,r);
    for(LNode *r=head;r->next!=NULL;r=r->next){
         cout<<r->next->data<<" ";
    }
    cout<<endl;
    Transpose(head,r);
    for(LNode *r=head;r->next!=NULL;r=r->next){
         cout<<r->next->data<<" ";
    }
    return 0;
}
复制代码

结果: 在这里插入图片描述

3.求最值

#include <bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;

//尾插法
void createLinkListR(LNode *&head,LNode *&r){
    head->next=NULL;
    LNode *p=NULL;
    r=head;
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        p=new LNode();
        p->next=NULL;
        cin>>p->data;
        p->next=r->next;
        r->next=p;
        r=p;
    }
}

int maxData(LNode *head){
    LNode *p,*q;
    int max=head->next->data;
    q=p=head->next;
    while(p!=NULL)
    {
        if(max<p->data)
        {
            max=p->data;
            q=p;
        }
        p=p->next;
    }
    return q->data;
}

int main(){
    LNode *head=new LNode();
    LNode *r;
    createLinkListR(head,r);   
    cout<<maxData(head)<<endl;
    return 0;
}
复制代码

4.归并

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;

//尾插法
void createLinkListR(LNode *&head,LNode *&r){
    head->next=NULL;
    LNode *p=NULL;
    r=head;
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        p=new LNode();
        p->next=NULL;
        cin>>p->data;
        p->next=r->next;
        r->next=p;
        r=p;
    }
}

//归并
void merge(LNode *A,LNode *B,LNode *&C)
{
    LNode *p=A->next;
    LNode *q=B->next;
    LNode *r;
    C=A;
    C->next=NULL;
    free(B);
    r=C;
    while(p!=NULL &&q!=NULL)
    {
        if(p->data<=q->data)
        {
            r->next=p;
            p=p->next;
            r=r->next;
        }
        else
        {
            r->next=q;
            q=q->next;
            r=r->next;
        }
    }

    if(p!=NULL)
        r->next=p;
    if(q!=NULL)
        r->next=q;
}


int main(){
    LNode *A=new LNode();
    LNode *B=new LNode();
    LNode *C;
    LNode *r;
    LNode *q;
    createLinkListR(A,r);
    createLinkListR(B,q);
    merge(A,B,C);
    for(LNode *r=C;r->next!=NULL;r=r->next)
    {
        cout<<r->next->data<<" ";
    }
    return 0;
}
复制代码
分类:
后端
标签: