数据结构第一章--线性表

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

1.逻辑结构

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

2.存储结构

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

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

性能具体功能顺序存储链式存储
空间性能存储分配一次性分配动态分配(优)
空间性能存储密度
(下面会有解释)
=1(优)<1
时间性能查找O((n+1)/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.静态链表

静态链表的增删改查操作:https://blog.csdn.net/qq_45137584/article/details/116567741
结点类型定义:
在这里插入图片描述
特点:一次性分配所有内存
在这里插入图片描述

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;
}

下面这题是不含头结点的合并
剑指 Offer 25. 合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 
        ListNode *p=l1;ListNode *q=l2;
        ListNode *r,*head;
        if(p!=NULL&&q!=NULL){
            if(p->val<=q->val){
                head=p;
                p=p->next;
            }else{
                head=q;
                q=q->next;
            }
            r=head;
            while(p!=NULL&&q!=NULL)
            {
                if(p->val<=q->val)
                {
                    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;
            }else{
                r->next=q;
            }
        }else if(p!=NULL||q!=NULL){
            if(p!=NULL){
                head=p;
            }else{
                head=q;
            }
        }
        else{
            head=NULL;
        }
        return head;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值