ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-1-23数据结构总结(1)

2022-01-23 16:31:52  阅读:137  来源: 互联网

标签:结点 NULL return LNode 23 int next 2021 数据结构


线性表包含顺序表(顺序存储)和链表(链式存储)

 

1、静态分配的顺序表实现

​#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;    //初始长度为0
}


//基本操作--向顺序表插入新元素
bool ListInsert(SqList &L, int i; int e){
    if(i<1||i>L.length+1)   //判断i的范围是否有效,顺序表下标从1开始,但是数组下标从0开始
        return false;
    if(L.length>=MaxSize)   //  当前存储空间已满,不能插入
        return false;
    for(int j=L.length; j>=i; j--)  //将第i个及之后的元素向后移
        L.data[j]=L.data[j-1];
    L.data[i-1]=e;  //第i个位置放入e
    L.length++:
    return ture;
}
//时间复杂度:最好、最坏、平均 ==== O(1)、O(n)、O(n)


//基本操作--向顺序表删除新元素
bool ListDelect(SqList &L, int i; int &e){  //删除的值e需要返回,加上取地址符&
    if(i<1||i>L.length+1)   //判断i的范围是否有效,顺序表下标从1开始,但是数组下标从0开始
        return false;
    e=L.data[i-1];  //将被删除的值赋值给e
    for(int j=i; j<L.length; j++)   //将第i个位置后的元素前移
        L.data[j-1]=L.data[j];  //顺序表下标从1开始,但是数组下标从0开始
    L.length--;
    return ture;
}
//时间复杂度:最好、最坏、平均 ==== O(1)、O(n)、O(n)


int main(){
    SqList L;    //声明一个顺序表
    InitList(L);    //初始化顺序表
    //.........
    for(int i=0; i<L.length; i++)    //访问并打印顺序表各个元素
        printf("data[%d]=%d\n", i, L.data[i]);
    ListInsert(L,3,3);
    int e=-1;
    if(ListDelect(L, 3, e))
        printf("已删除第3个元素,删除元素值为=%d\n",e);
    else
        printf("位序i不合法,删除失败\n");
    return 0;
}

 

2、动态分配的顺序表实现

#include<stdlib.h>    //malloc、free函数的头文件

#define InitSize 10    //默认最大长度
typedef struct{
    int *data;    //指示动态分配数组的指针
    int MaxSize;    //顺序表的最大容量
    int length;    //定义当前长度
}SqList;


//基本操作--初始化一个动态分配的顺序表
void InitList(Seqlist &L){
    //用malloc函数申请一片连续的存储空间
    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);    //释放原来的内存空间
}


//基本操作--顺序表的按位查找
ElemType GetElem(SeqList L, int i){
    return L.data[i-1];
}


//基本操作--顺序表的按值查找
int LocateElem(SeqList L, ElemType e){
    for(int i=0; i<L.length; i++)
        if(L.data==e)
            return i+1;     //下标为i的元素值为e,返回其位序i+1
    return 0;
}
//时间复杂度:最好、最坏、平均 ==== O(1)、O(n)、O(n)


int main(){
    SqList L;    //声明一个顺序表
    InitList(L);    //初始化顺序表
    //......向顺序表中随意插入几个元素....
    IncreaseSize(L, 5);
    return 0;
}

 

3、带头结点单链表的实现

#include<stdlib.h>    //malloc、free函数的头文件

typedef struct LNode{
    ElemType data;   //每个结点存放一个数据元素
    struct LNode *next;    //指针指向下一个结点
}LNode, *LinkList;
/*
表示一个单链表,只需声明一个头指针L
LNode *L;    //强调这是一个结点
LinkList L;    //强调这是一个单链表
以上都能声明一个头结点,两句效果相同
*/


//初始化一个单链表(带头结点)
bool InitList(LinkList &L){
    L = (LNode *)malloc(sizeof(LNode));
    if(L==NULL)    //内存不足,分配失败
        return false;
    L->next=NULL;     //头结点之后没有结点
    return true;
}


//尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
    int x;
    L=(LinkList)malloc(sizeof(LNode));    //创建头结点
    LNode *s,*r=L;
    scanf("%d",&x);
    while(x!=9999){    //输入结点值为9999表示结束
        s=(LNode *)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;    //永远保持r在最后一个结点
        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){    //输入结点值为9999表示结束
        s=(LNode *)malloc(sizeof(LNode));
        s->next=x;
        s->next=L->next;
        L->next=s;
        scanf("%d",&x);
    }
    return L;
}
//头插法创建的链表输入的元素与实际存储顺序相反


//指定结点的后插操作
bool InsertNextNode(LNode *P, ElemType e){
    if(p==NULL)
        return false;
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if(s==NULL)    //内存分配失败
        return false;
    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插入
    s->data=p->data;     //将p与s的数据互换
    p->data=e;      //将e值覆盖p中元素
    return true;
}


//单链表按位查找,返回第i个元素
LNode * GetElem(LinkList L, int i){
    if(i<0)
        return false;
    LNode *p;    //指针p指向当前扫描到的结点
    int j=0;    //表示p指向的是第几个结点
    p=L;     //初始p指向头结点
    while(p!=NULL&&j<i){    //循环找到第i个结点
        p=p->next;
        j++;
    }
    return p;
}


//按值查找
LNode * LocateElem(LinkList L, ElemType e){
    LNode *p=L->next;
    while(p!=NULL&&p->data!=e)
        p=p->next;
    return p;
}


//按位序插入(带头结点)
bool ListInsert(LinkList &L, int i, ElemType e){
    if(i<1)
        return false;
    LNode *p=GetElem(L,i-1);    //找到第i-1个结点
    return InsertNextNode(p,e);
}


//删除指定结点P
bool DeleteNode(LNode *P){
    if(p==NULL||p->netx==NULL)    //P不能是最后一个结点
        return false;
    LNode *q=p->next;    //令q指向*p的后继结点
    p->data=p->next->data;    //和后继结点交换数据域
    p->next=q->next;    //将*q结点从链中断开
    free(q);
    return true;
}


//按位序删除(带头结点)
bool ListDelect(LinkList &L, int i, ElemType &e){
    if(i<1)
        return false;
    LNode *p=GetElem(L,i-1);    //找到第i-1个结点
    e=p->data;
    return DeleteNode(P);
}


//判断单链表是否为空(带头结点)
bool Empty(LinkList L){
    return(L->next==NULL);
}
//如果不带头结点,则是return(L==NULL);


void test(){
    LinkList L;    //声明一个指向单链表的指针
    //初始化一个空单链表
    InitList(L);
    return 0;
}

 

4、双链表的实现

#include<stdlib.h>

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;    //头结点的prior永远指向NULL
    L->next=NULL;     //头结点之后暂时没有结点
    return true;
}


//双链表的插入--在p结点之后插入s结点
bool InsertNextDNode(DNode *p, DNode *s){
    if(p==NULL||s==NUll)
        return false;
    s->next=p->next;
    if(p->next!=NULL)    //如果p没有后继结点
        p->next->prior=s;
    s->prior=p;
    p->next=s;
}


//双链表的删除--删除p结点的后继结点
bool DeleteNextDNode(DNode *P){
    if(p==NULL)
        return false;
    DNode *q=p->next;
    if(q==NULL)
        return false;
    p->next=q->next;
    if(q->next!=NULL)
        q->next->prior=p;
    free(q);
    return ture;
}
void DestoryList(DLinkList &L){
    while(L->next!=NULL)
        DeleteNextDNode(L);
    free(L);
    L=NULL;
}


//判断双链表是否为空(带头结点)
bool Empty(DLinkList L){
    return(L->next==NULL);
}


void testDLinkList(){
    DLinkList L;
    InitDLinkList(L);
    ......
    return 0;
}

标签:结点,NULL,return,LNode,23,int,next,2021,数据结构
来源: https://blog.csdn.net/weixin_42637873/article/details/122650731

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有