数据结构与算法----线性表

定义

具有相同数据类型的n个数据元素的有限序列一种逻辑结构(表示数据之间的一一对应关系)

数据元素:数据元素是数据的基本单位;有数据项构成。

基本操作

lnitList(&L):初始化表。构建一个空的线性表

DestroyList(&L):销毁操作,销毁线性表,释放线性表L所占的内存空间。

ListInsert(&L,i,e): 插入操作。在表L的第i个位置上插入指定元素e。

ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

LocateElem(L,e):按值查找操作。

GetElem(L,i):按位查找操作。

Length(L):求表长。

Print List(L):输出操作。

Empty(L):判空操作。

存储

顺序表

定义:用顺序存储的方式实现线性表

静态分配

#include <stdio.h>
#define MaxSize 10
typedef struct{
    int data[MaxSize];
    int length;
}SqList;
​
void InitList(SqList &L){
    for(int i=0;i<MaxSize;i++){
        L.data[i]=0;
    }
    L.length=0;
}
int main()
{
    SqList L;
    InitList(L);
    return 0;
}

动态分配

C:malloc动态申请内存空间;free动态释放内存空间

C++:new动态申请内存空间;delete动态释放内存空间

#include <stdlib.h>
#include <stdio.h>
#define InitSize 10
typedef struct{
    int *data;
    int MaxSize;
    int length;
}SeqList;
​
void InitList(SeqList &L){
    L.data=(int *)malloc(InitSize*sizeof(int));
    L.length=0;
    L.MaxSize=InitSize;
}
void IncreaseSize(SeqList &L,int len){
    int *p=L.data;
    L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
    for(int i=0; i<L.length;i++){
        L.data[i]=p[i];
    }
    L.MaxSize=L.MaxSize+len;
    free(p);
}
int main()
{
    SeqList L;
    InitList(L);
    IncreaseSize(L,7);
    return 0;
}

特点

  • 随机访问,可以在O(1)时间内找到第i个元素

  • 存储密度高,每个节点只存储数据元素

  • 拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)

  • 插入,删除操作不方便,需要移动大量元素。

基本操作

  • 插入 删除 按位查找

#include <stdlib.h>
#include <stdio.h>
#define MaxSize 10
typedef struct{
    int data[MaxSize];
    int length;
}SqList;
​
void InitList(SqList &L){
    for(int i=0;i<MaxSize;i++){
        L.data[i]=0;
    }
    L.length=0;
}
bool ListInsert(SqList &L,int i, int e){
    
    for(int j=L.length;j>=i;j--){
        L.data[j]= L.data[j-1];
    }
    L.data[i-1] = e;
    L.length++;
    return true;
}
bool ListDelete(SqList &L,int i, int &e){
    e=L.data[i-1];
    for(int j=i;j<L.length;j++){
        L.data[j-1]= L.data[j];
    }
    L.length--;
    return true;
}
int GetElem(SqList L ,int i){
    return L.data[i-1]; 
}
int LocateElem(SqList L,int e){
    for(int i = 0;i<MaxSize;i++){
        
        if(L.data[i]==e){
            return i+1;
        }
    }
    return 0;
}
int main()
{
    SqList L;
    InitList(L);
    ListInsert(L,3,3);
    int e= -1;
    ListDelete(L,3,e);
    int a = GetElem(L,3);
    return 0;
}

单链表

定义

struct LNode{
    ElemType data;
    struct LNode *next;
};
//增加节点
struct LNode *p = (struct LNode*)malloc(sizeof(struct LNode)); 

typedef<数据类型><别名>

不带头结点单链表

typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;
bool Initlist(LinkList &L){
    L= NULL;
    return true;
}
void test(){
    LinkList L;(没有创建结点)
    Initlist(L);
}

带头结点单链表(写代码方便)

typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;
bool Initlist(LinkList &L){
    L= (LNode *)malloc(sizeof(LNode));
    if(L==NUll){
        return false;
    }
    L->next =NULL;
    return true;
}
void test(){
    LinkList L;(没有创建结点)
    Initlist(L);
}

基本操作

ListInsert(&L,i,e):插入操作。按位序删除

//带头结点
bool ListInsert(LinkList &L,int i,Elemtype e){
    if(i<1)
        return false;
    LNode *p;
    int j=0;
    p = L;//指向头结点(第0个节点)不存数据。
    while(p!=NULL&& j<i-1){
        p= p->next;
        j++;
    }
    if(p==NULL){
        return false;
    }
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data= e;
    s->next= p->next;
    p->next= s;
    return true;
}
//不带头结点
bool ListInsert(LinkList &L,int i,Elemtype e){
    if(i<1)
        return false;
    if(i==1){
        LNOde *s=(LNode *)malloc(sizeof(LNode));
        s->data=e;
        s-next=L;
        L=s;
        return ture;
    }
    LNode *p;
    int j=1;
    p = L;//第一个节点不是头结点
    while(p!=NULL&& j<i-1){
        p= p->next;
        j++;
    }
    if(p==NULL){
        return false;
    }
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data= e;
    s->next= p->next;
    p->next= s;
    return true;
}
//前插操作
bool InsertPriorNode(LNode *p,ElemType e){
    if(p==NULL)
        return false;
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if(s==NULL)
        return false;//内存分配失败
    s->next = p->next;
    p->next = s;
    s->data = p->data;
    p->data = e;
    return ture;
}
//按位序删除(带头结点)
bool ListDelete(LinkList &L int i, ElemType &e){
    if(i<1)
        return false;
    LNode *p;
    int j=0;
    int j=0;
    p = L;//指向头结点(第0个节点)不存数据。
    while(p!=NULL&& j<i-1){
        p= p->next;
        j++;
    }
    if(p==NULL){
        return false;
    }
    if(p->next == NULL){
        return false;
    }
    LNode *q =p->next;
    e = q->data;
    p->next=q->next;
    free(q);
    return true;
}
//删除指定结点
bool DeleteNode(LNode *p){
    if(p==NULL){
        return false;
    }
    LNode *q=p->next;
    p->data=p->next->data;
    p->next=q->next;
    free(q);
    return true;
}
//尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
    int x;
    L=(LinkList)malloc(sizeof(LNode));
    LNode *s,*r=L;
    scanf("%d",&x);
    while(x!=9999){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        scanf("%d",&x);
    }
    r->next=null;
    return L;
}
//头插法建立单链表
LinkList List_HeadInsert(LinkList &L){
    LNode *s;
    int x;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    scanf("%d",&x);
    while(x!=9999){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=L->next;
        L->next=s;
        scanf("%d",&x);
    }
    return L;
}
//链表逆置(头插法)
#include<stdio.h>
#include<malloc.h>
typedef struct LNode{
    int data;
    struct LNode *next;
}LNode,*LinkList;
​
LinkList Reverse(LinkList &L)
{
    LinkList p,q;
    p=L->next;
    L->next=NULL;   //重新构造单链表
    while(p!=NULL)
    {
        q=p;
        p=p->next;
        
        q->next=L->next;  //头插法 
        L->next=q;
    } 
    return L;
} 
​
​
int main()
{
    LinkList A = (LinkList)malloc(sizeof(LNode));
    LinkList a1 = (LinkList)malloc(sizeof(LNode));
    LinkList a2 = (LinkList)malloc(sizeof(LNode));
    LinkList a3 = (LinkList)malloc(sizeof(LNode));
    LinkList a4 = (LinkList)malloc(sizeof(LNode));
    A->next=a1;
    a1->next=a2;
    a2->next=a3;
    a3->next=a4;
    a4->next=NULL;
    a1->data=1;
    a2->data=2;
    a3->data=3;
    a4->data=4;
    LinkList p=A->next;
    printf("A中元素:");
    while(p){
        printf("%d ",p->data);
        p=p->next;
    }
    p=Reverse(A);
    printf("\n单链表逆置之后A中的元素:\n");
    for(p=p->next;p!=NULL;p=p->next)
    {
        printf("%d ",p->data);
    }
    return 0;
}    

顺序表输出所有元素跟单链表输出时间复杂度一样

双链表

初始化双链表

typedef struct DNode{
    ElemType data;
    struct DNode *prior,*next;
}DNode,*DLinklist;
bool InitDLinkList(Dlinklist &L){
    L=(DNode *)malloc(sizeof(DNode));
    if(L==NULL){
        return false;
    }
    L->prior = NULL;
    L->next = NULL;
    return true;
}
//插入
//关注插入的结点,s的prior和next都要有人
bool InsertNextDNode(DNode *p,DNode *s){
    if(p==NUll||s==NULL)
        return false;
    s->next=p->next;
    if(p->next!=NULL)
        p->next->prior=s;
    s->prior=p;
    p->next=s;
}
//删除p的后继结点
//想要删除谁,关注谁
bool DeleteNextDNode(DNode *p,){
    if(p==NUll)
        return false;
    DNode *q=p->next;
    p->next=q->next;
    if(q->next!=NULL)
        q->next->prior=p;
    free(q);
    return true;
}
//释放各个结点
void DestoryList(DLinklist &L){
    while(L->next!=NULL)
        DeleteNextDNode(L);
    free(L);
    L=NULL;
}
​
void testDLinkList(){
    DLinklist L;
    InitDLinkList(L);
}

循环单链表

约瑟夫环-

typedef struct LNode{
    ElemType data;
    struct LNode
}LNode,*LinkList;
​
//初始化一个循环单链表
bool InitList(LinkList &L){
    L = (LNode*)malloc(sizeof(LNode));
    if(L==NULL)
        return false;
    L->next = L;
    return true;
}
//是否为空
bool Empty(LinkList L){
    if(L->next ==L)
        return true;
    else
        return false;
}
//判断结点p是否为循环单链表的表尾结点
bool isTail(LinkList L,LNode *p){
    if(p->next==L)
        return true;
    else
        return false;
}

循环双链表

typedef struct DNode{
    ElemType data;
    struct DNode *prior,*next;
}LNode,*LinkList;
​
//初始化一个循环单链表
bool InitDLinkList(DLinkList &L){
    L = (DNode*)malloc(sizeof(DNode));
    if(L==NULL)
        return false;
    L->prior = L;
    L->next = L;
    return true;
}
//是否为空
bool Empty(LinkList L){
    if(L->next ==L)
        return true;
    else
        return false;
}
//判断结点p是否为循环双链表的表尾结点
bool isTail(DLinkList L,DNode *p){
    if(p->next==L)
        return true;
    else
        return false;
}
//插入
bool InsertNextDNode(DNode *p,DNode *s){
    s->next=p->next;
    p->next->prior=s;
    s->prior=p;
    p->next=s;
}

静态链表

分配一整片连续的内存空间,各个结点集中安置。

#define MaxSize 10
typedef struct{
    ElemType data;
    int next;
}SLinkList[MaxSize];
void testSLinkList(){
    struct Node a[MaxSize];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值