数据结构-线性表的实现

线性表的实现

1、顺序表

1.1、顺序表-静态

1.1.1、静态顺序表的基本操作

#include <stdio.h>
#include <stdlib.h>

#define MaxSize 10
typedef struct {
    int data[MaxSize];
    int length;
}SqList;

//初始化静态顺序表
void InitSqList(SqList *L)
{
    //将所有数据元素设置为默认初始值
    for(int i=0;i<MaxSize;i++)
    {
        L->data[i]=0;
    }
    //顺序表初始长度为0
    L->length=0;
}

//判断静态顺序表是否已满
int SqListFull(SqList *L)
{
    if(L->length==MaxSize)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//判断静态顺序表是否为空
int SqListEmpty(SqList *L)
{
    if(L->length==0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//向静态顺序表中插入数据元素
int InsertElement(SqList *L,int locate,int e)
{
    //locate的值不合法
    if(locate<0 || locate>L->length)
    {
        return 0;
    }

    //若静态顺序表已满,则不能进行插入操作
    int flag;
    flag= SqListFull(L);
    if(flag==1)
    {
        return 0;
    }

    //如果下标locate为length,表示在顺序表的后方加入一个数据元素
    if(locate!=L->length)
    {
        //将下标为locate后面所有的数据元素后移一位
        for(int i=L->length-1;i>=locate;i--)
        {
            L->data[i+1]=L->data[i];
        }
    }
    //在locate位置插入数据元素e
    L->data[locate]=e;
    //静态顺序表的长度加1
    L->length++;
    return 1;
}

//删除静态顺序表中的数据元素
int DeleteElement(SqList *L,int locate)
{
    //locate的值不合法
    if(locate<0 || locate>L->length-1)
    {
        return 0;
    }
    int flag;
    flag= SqListEmpty(L);
    if(flag==1)
    {
        return 0;
    }
    //核心部分,依次将后面元素的值赋值给前面的元素
    for(int i=locate;i<L->length-1;i++)
    {
        L->data[i]=L->data[i+1];
    }

    //静态顺序表的表长减1
    L->length--;

    return 1;
}

//按位查找
int getElement(SqList L,int locate)
{
    if(locate<0 || locate>L.length-1)
    {
        return -1;
    }
    return L.data[locate];
}

//按值查找
int getLocate(SqList L,int e)
{
    for(int i=0;i<L.length;i++)
    {
        if(L.data[i]==e)
        {
            return i;
        }
    }
    return -1;
}

//打印静态顺序表
void printSqList(SqList L)
{
    int flag= SqListEmpty(&L);
    if(flag==1)
    {
        printf("此静态顺序表为空!\n");
    }
    else
    {
        printf("此静态顺序表长度为%d\n",L.length);
        for(int i=0;i<L.length;i++)
        {
            printf("(%d,%d)\n",i,L.data[i]);
        }
    }

}


int main()
{
    //初始化一个静态顺序表
    SqList L;
    InitSqList(&L);

    //生成一个静态顺序表
    int flag;
    for(int i=0;i<8;i++)
    {
        //向静态顺序表中插入数据元素
        flag= InsertElement(&L,i,i*i);
        if(flag==1)
        {
            printf("插入成功!\n");
        }
        else
        {
            break;
        }
    }
    //打印生成的静态顺序表
    printSqList(L);

    //删除数据元素
    flag= DeleteElement(&L,3);
    if(flag==1)
    {
        //打印删除数据元素后的静态顺序表
        printSqList(L);
    }

    //按位查找
    flag= getElement(L,3);
    if(flag!=-1)
    {
        printf("值为%d\n",flag);
    }
    else
    {
        printf("查找失败\n");
    }

    //按值查找
    flag= getLocate(L,36);
    if(flag!=-1)
    {
        printf("下标为%d\n",flag);
    }
    else
    {
        printf("未找到!\n");
    }
    return 0;
}

1.2、顺序表-动态

1.2.1、动态顺序表的基本操作

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

//默认的最大长度
#define InitSize 10

typedef struct{
    //指示动态分配数组的指针
    int* data;
    //顺序表的最大容量
    int MaxSize;
    //顺序表的当前长度
    int length
}SeqList;

//初始化动态顺序表
void InitSeqList(SeqList* L)
{
    L->data=(int *) malloc(sizeof(int)*InitSize);
    L->MaxSize=InitSize;
    L->length=0;
}

//动态的增加顺序表的容量
void IncreaseSize(SeqList* L,int len)
{
    //指针p指向动态顺序表的数组
    int *p=L->data;
    //申请一个新的空间,并且指针data指向这片新的空间
    L->data=(int *) malloc(sizeof(int)*(L->MaxSize+len));
    //将旧空间里存放的数据元素复制到新空间里
    for(int i=0;i<L->length;i++)
    {
        L->data[i]=p[i];
    }
    //将动态顺序表的最大容量进行修改
    L->MaxSize=L->MaxSize+len;
    //将旧空间的内存进行释放
    free(p);
}

//判断动态顺序表是否为空
int SeqListEmpty(SeqList* L)
{
    if(L->length==0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//判断动态顺序表是否已满
int SeqListFull(SeqList *L)
{
    if(L->length==L->MaxSize)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//向动态顺序表中插入数据元素
int InsertElement(SeqList *L,int locate,int e)
{
    //locate的值不合法
    if(locate<0 || locate>L->length)
    {
        return 0;
    }

    //若动态顺序表已满,则默认扩充5个长度
    int flag;
    flag= SeqListFull(L);
    if(flag==1)
    {
        IncreaseSize(L,5);
    }

    //如果下标locate为length,表示在顺序表的后方加入一个数据元素
    if(locate!=L->length)
    {
        //将下标为locate后面所有的数据元素后移一位
        for(int i=L->length-1;i>=locate;i--)
        {
            L->data[i+1]=L->data[i];
        }
    }
    //在locate位置插入数据元素e
    L->data[locate]=e;
    //静态顺序表的长度加1
    L->length++;
    return 1;
}


//删除动态顺序表中的数据元素
int DeleteElement(SeqList *L,int locate)
{
    //locate的值不合法
    if(locate<0 || locate>L->length-1)
    {
        return 0;
    }
    int flag;
    flag= SeqListEmpty(L);
    if(flag==1)
    {
        return 0;
    }
    //核心部分,依次将后面元素的值赋值给前面的元素
    for(int i=locate;i<L->length-1;i++)
    {
        L->data[i]=L->data[i+1];
    }

    //动态顺序表的表长减1
    L->length--;

    return 1;
}

//按位查找
int getElement(SeqList L,int locate)
{
    if(locate<0 || locate>L.length-1)
    {
        return -1;
    }
    return L.data[locate];
}

//按值查找
int getLocate(SeqList L,int e)
{
    for(int i=0;i<L.length;i++)
    {
        if(L.data[i]==e)
        {
            return i;
        }
    }
    return -1;
}

//打印动态态顺序表
void printSqList(SeqList L)
{
    int flag= SeqListEmpty(&L);
    if(flag==1)
    {
        printf("此动态顺序表为空!\n");
    }
    else
    {
        printf("此动态顺序表长度为%d\n",L.length);
        for(int i=0;i<L.length;i++)
        {
            printf("(%d,%d)\n",i,L.data[i]);
        }
    }

}

int main()
{
    //生成一个动态顺序表
    SeqList L;
    InitSeqList(&L);
    //插入数据
    int flag;
    for(int i=0;i<9;i++)
    {
        flag=InsertElement(&L,i,i*i);
        if(flag==1)
        {
            printf("插入成功!\n");
        }
        else
        {
            break;
        }
    }

    //打印生成的动态顺序表
    printSqList(L);

    //删除数据元素
    flag= DeleteElement(&L,3);
    if(flag==1)
    {
        //打印删除数据元素后的动态顺序表
        printSqList(L);
    }

    //按位查找
    flag= getElement(L,3);
    if(flag!=-1)
    {
        printf("值为%d\n",flag);
    }
    else
    {
        printf("查找失败\n");
    }

    //按值查找
    flag= getLocate(L,36);
    if(flag!=-1)
    {
        printf("下标为%d\n",flag);
    }
    else
    {
        printf("未找到!\n");
    }
    return 0;
    
}

2、链表

2.1、单链表

2.1.1、单链表的建立

#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
typedef struct LinkList{
    int id;
    struct LinkList *next;
}LNode,*LinkList;

//头插法(不常用)
LinkList List_InsertHead(LinkList L,int n)
{
    L=(LinkList) malloc(sizeof(LinkList));
    if(L==NULL)
    {
        return L;
    }
    L->next=NULL;
    LNode *p;
    p=L;
    for(int i=1;i<=n;i++)
    {
        LNode *s=(LNode *) malloc(sizeof(LNode));
        s->id=i;
        s->next=p->next;
        p->next=s;
    }
    return L;
}

//尾插法(常用)
LinkList List_InsertTail(LinkList L,int n)
{
    L=(LinkList) malloc(sizeof(LinkList));
    if(L==NULL)
    {
        return L;
    }
    L->next=NULL;

    LNode *p=L;

    for(int i=1;i<=n;i++)
    {
        LNode *s=(LNode *) malloc(sizeof(LNode));
        s->id=i;
        s->next=NULL;
        p->next=s;
        p=s;
    }
    return L;
}


void printLinkList(LinkList L)
{
    LNode *p=L;
    while (p->next!=NULL)
    {
        p=p->next;
        printf("%d",p->id);
        printf("\n");
    }
}

int main()
{
    //头插法
    printf("--------------------------头插法------------------------------\n");
    LinkList L=NULL;
    L= List_InsertHead(L,5);
    if(L!=NULL)
    {
        printLinkList(L);
    }
    else
    {
        printf("failed!!!\n");
    }


    //尾插法
    printf("--------------------------尾插法------------------------------\n");
    LinkList L1=NULL;
    L1= List_InsertTail(L1,5);
    if(L1!=NULL)
    {
        printLinkList(L1);
    }
    else
    {
        printf("failed!!!\n");
    }

    return 0;
}

2.1.2、单链表的插入操作

#include <malloc.h>
#include "stdio.h"

//带头结点的单链表插入操作
typedef struct Linklist {
    int id;
    struct Linklist *next;
}LNode,*Linklist;

//指定位置插入操作
int ListInsert(Linklist L,int i,int e)//i为第几个位置(第0个为头结点)
{
    if(i<1)
    {
        return 0;
    }
    LNode *p;//指针p指向当前扫描到的节点
    int j=0;//当前p指向的是第几个节点
    p=L;//L指向头结点,头结点为第0个节点(不存数据)

    while (p!=NULL && j<i-1)
    {
        p=p->next;
        j++;
    }
    if(p==NULL)
    {
        return 0;
    }

    LNode *s= (LNode *)malloc(sizeof(LNode));
    s->id=e;
    s->next=p->next;
    p->next=s;
    return 1;
}

//指定节点后插操作
int InsertNextNode(LNode *p,int e)
{
    if(p==NULL)
    {
        return 0;
    }
    LNode *s=(LNode *)malloc(sizeof(LNode));
    if(s==NULL)
    {
        return 0;
    }
    s->id=e;
    s->next=p->next;
    p->next=s;
    return 1;
}

//指定节点前插操作
int InsertPriorNode(LNode *p,int e)
{
    if(p==NULL)
    {
        return 0;
    }
    LNode *s=(LNode *) malloc(sizeof(LNode));
    if(s==NULL)
    {
        return 0;
    }
    s->id=p->id;
    s->next=p->next;
    p->next=s;
    p->id=e;
    return 1;

}


int main()
{
	//单链表的逻辑
    LNode l1,l2,l3,l4;

    l1.id=1;
    l2.id=2;
    l3.id=3;
    l4.id=4;

    l1.next=&l2;
    l2.next=&l3;
    l3.next=&l4;
    l4.next=NULL;

    //头指针
    Linklist l;
    l->id=0;
    l->next=&l1;
    int flag;

    /*指定位置插入操作
    flag=ListInsert(l,2,90);*/

    /*指定节点后插操作
    flag=InsertNextNode(&l2,10000);*/

    //指定节点前插操作
    flag= InsertPriorNode(&l2,1890);
    if(flag==0)
    {
        printf("failed!!!");
        printf("\n");
    }
    if(flag==1)
    {
        printf("succeed");
        printf("\n");
    }

    LNode *pi;
    pi=&l1;
    while(pi!=NULL)
    {
        printf("%d",pi ->id);
        printf("\n");
        pi=pi->next;
    }
    return 0;
}


2.1.3、单链表的查询操作

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

typedef struct LinkList{
    int id;
    struct LinkList *next;
}LNode,*LinkList;

//按值查找
int searchElement(LinkList L,int e)
{
    int j;
    LNode *p=L->next;
    j=1;
    while (p!=NULL && p->id!=e)
    {
        p=p->next;
        j++;
    }
    return j;
}

//按位查找
int searchLocate(LinkList L,int locate)
{
    LNode  *p=L;
    int j=0;
    while (p!=NULL && j!=locate)
    {
        p=p->next;
        j++;
    }
    return p->id;
}


int main()
{
    LinkList L=(LinkList) malloc(sizeof(LinkList));
    L->next=NULL;

    LNode *p=L;
	
	//生成一个单链表
    for(int i=1;i<=5;i++)
    {
        LNode *s=(LNode *) malloc(sizeof(LNode));
        s->id=i;
        s->next=NULL;
        p->next=s;
        p=s;
    }
    //按值查找
    int e=2;
    int locate= searchElement(L,e);
    printf("值%d在第%d个\n",e,locate);

    //按位查找
    int locate1=3;
    int e1= searchLocate(L,locate1);
    printf("第%d个值为%d\n",locate1,e1);

    return 0;
}

2.1.4、单链表的删除操作

#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"


typedef struct Linklist {
    int id;
    struct Linklist *next;
}LNode,*Linklist;

int ListDelete(Linklist L,int i)
{
    if(i<1)
    {
        return 0;
    }
    LNode *p;
    int j;

    p=L;
    j=0;
    while (p!=NULL && j<i-1)
    {
        p=p->next;
        j++;
    }
    if(p==NULL)//如果i值不合法,则p==NULL
    {
        return 0;
    }

    int n;
    LNode *q;
    q=p->next;
    n=q->id;
    p->next=q->next;
    free(q);


    return n;
}

int main()
{
    Linklist L= (Linklist)malloc(sizeof(LNode));
    L->next=NULL;
    LNode *p=L;
    //生成一个单链表
    for(int i=1;i<=5;i++)
    {
        LNode *s=(LNode *) malloc(sizeof(LNode));
        s->id=i;
        s->next=p->next;
        p->next=s;
        p=s;
    }

    int flag;
    flag=ListDelete(L,2);
    if(flag==0)
    {
        printf("failed!!!");
        printf("\n");
    }
    else
    {
        printf("succeed!!!\n");
        printf("%d is deleted\n",flag);
        printf("\n");
    }
    //打印删除操作后的单链表
    LNode *pi=L;
    while (pi->next!=NULL)
    {
        pi=pi->next;
        printf("%d\n",pi->id);
    }


    return 0;
}

2.1.5、单链表的长度计算

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

typedef struct LinkList{
    int id;
    struct LinkList *next;
}LNode,*LinkList;


int length(LinkList L)
{
    LNode *p=L;
    int len=0;
    while(p->next!=NULL)
    {
        p=p->next;
        len++;
    }
    return len;

}

int main()
{
    LinkList L=(LinkList) malloc(sizeof(LinkList));
    L->next=NULL;

    LNode *p=L;
	//生成一个单链表
    for(int i=1;i<=5;i++)
    {
        LNode *s=(LNode *) malloc(sizeof(LNode));
        s->id=i;
        s->next=NULL;
        p->next=s;
        p=s;
    }

    int len=length(L);
    printf("单链表L共有%d个节点\n",len);

    return 0;
}

2.2、双链表

2.2.1、双链表的建立

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

typedef struct DLinkList{
    struct DLinkList *next;
    struct DLinkList *prior;
    int data;
}DNode,*DLinkList;

//初始化双链表
DLinkList InitDLinkList(DLinkList L)
{
    L=(DNode *) malloc(sizeof(DNode));
    if(L==NULL)
    {
        return NULL;
    }
    L->next=NULL;//空链表
    L->prior=NULL;//头结点的prior永远指向NULL
    return L;
}

//打印双链表
void printDLinkList(DLinkList L)
{
    DNode *p=L;
    while (p->next!=NULL)
    {
        p=p->next;
        printf("%d",p->data);
        printf("\n");
    }
}

//尾插法(常用)
DLinkList List_InsertTail(DLinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    DNode *p=L;

    for(int i=1;i<=n;i++)
    {
        DNode *s=(DNode *) malloc(sizeof(DNode));
        s->data=i;
        s->next=NULL;
        s->prior=p;
        p->next=s;
        p=s;
    }
    return L;
}

//头插法(不常用)
DLinkList List_InsertHead(DLinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    DNode *p=L;

    for(int i=1;i<=n;i++)
    {
        DNode *s=(DNode *) malloc(sizeof(DNode));
        s->data=i;
        s->next=p->next;
        if(p->next!=NULL)
        {
            p->next->prior=s;
        }
        s->prior=p;
        p->next=s;
    }
    return L;
}


int main()
{
    DLinkList L;
    L=InitDLinkList(L);
    //尾插法
    //L= List_InsertTail(L,6);
    //头插法
    L= List_InsertHead(L,9);
    printDLinkList(L);


    return 0;
}

2.2.2、双链表的插入操作

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

typedef struct DLinkList{
    struct DLinkList *next;
    struct DLinkList *prior;
    int data;
}DNode,*DLinkList;

//初始化双链表
DLinkList InitDLinkList(DLinkList L)
{
    L=(DNode *) malloc(sizeof(DNode));
    if(L==NULL)
    {
        return NULL;
    }
    L->next=NULL;//空链表
    L->prior=NULL;//头结点的prior永远指向NULL
    return L;
}

//后插操作
int InsertNextDNode(DNode *p,DNode *s)
{
    if(p==NULL || s==NULL)
    {
        return 0;
    }
    s->data=999;
    s->next=p->next;
    if(s->next!=NULL)
    {
        s->next->prior=s;//p不为最后一个节点时需修改p的后继节点的前驱指针
    }
    s->prior=p;
    p->next=s;
    return 1;
}


//尾插法(常用)
DLinkList List_InsertTail(DLinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    DNode *p=L;

    for(int i=1;i<=n;i++)
    {
        DNode *s=(DNode *) malloc(sizeof(DNode));
        s->data=i;
        s->next=NULL;
        s->prior=p;
        p->next=s;
        p=s;
    }
    return L;
}

//前插操作(找到插入位置的前驱节点,在前驱节点执行后插操作)
int InsertPriorDNode(DNode *p,DNode *s)
{
    DNode *m=p->prior;
    int flag=InsertNextDNode(m,s);
    return flag;
}

void printDLinkList(DLinkList L)
{
    DNode *p=L;
    while (p->next!=NULL)
    {
        p=p->next;
        printf("%d",p->data);
        printf("\n");
    }
}

int main()
{
    DLinkList L;
    L=InitDLinkList(L);

    //创建一个双链表
    L= List_InsertTail(L,5);

    //带插入的结点
    DNode *s=(DNode *) malloc(sizeof(DNode));

    //后插操作
    //int flag=InsertNextDNode(L->next->next,s);

    //前插操作
    int flag= InsertPriorDNode(L->next->next->next->next,s);
    if(flag==1)
    {
        printDLinkList(L);
    }

    return 0;
}

2.2.3、双链表的删除操作

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

typedef struct DLinkList{
    struct DLinkList *next;
    struct DLinkList *prior;
    int data;
}DNode,*DLinkList;

//初始化双链表
DLinkList InitDLinkList(DLinkList L)
{
    L=(DNode *) malloc(sizeof(DNode));
    if(L==NULL)
    {
        return NULL;
    }
    L->next=NULL;//空链表
    L->prior=NULL;//头结点的prior永远指向NULL
    return L;
}

void printDLinkList(DLinkList L)
{
    DNode *p=L;
    while (p->next!=NULL)
    {
        p=p->next;
        printf("%d",p->data);
        printf("\n");
    }
}

//删除p结点的后继结点
int DeleteNextDnode(DNode *p)
{
    if(p==NULL)
    {
        return 0;
    }
    if(p->next==NULL)
    {
        return 0;
    }
    DNode *q=p->next;
    p->next=q->next;
    if(p->next!=NULL)
    {
        p->next->prior=p;
    }
    free(q);
    return 1;
}

//尾插法(常用)
DLinkList List_InsertTail(DLinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    DNode *p=L;

    for(int i=1;i<=n;i++)
    {
        DNode *s=(DNode *) malloc(sizeof(DNode));
        s->data=i;
        s->next=NULL;
        s->prior=p;
        p->next=s;
        p=s;
    }
    return L;
}

int DestoryDList(DLinkList L)
{
    int flag;
    while (L->next!=NULL)
    {
        flag= DeleteNextDnode(L);
    }
    free(L);
    L=NULL;
    return flag;
}
int main()
{
    DLinkList L;
    L=InitDLinkList(L);
    //生成一个双链表
    L= List_InsertTail(L,5);

    //删除结点操作(删除给定结点的后继结点)
    int flag= DeleteNextDnode(L->next->next);
    if(flag==1)
    {
        printDLinkList(L);
    }

    //销毁双链表操作
    /*
     int flag= DestoryDList(L);
     if(flag==1)
     {
         printDLinkList(L);
     }
     */

    return 0;

}

2.2.4、双链表的遍历操作

#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"

typedef struct DLinkList{
    struct DLinkList *next;
    struct DLinkList *prior;
    int data;
}DNode,*DLinkList;

//初始化双链表
DLinkList InitDLinkList(DLinkList L)
{
    L=(DNode *) malloc(sizeof(DNode));
    if(L==NULL)
    {
        return NULL;
    }
    L->next=NULL;//空链表
    L->prior=NULL;//头结点的prior永远指向NULL
    return L;
}

//后向遍历
void nextEveryone(DNode *p)
{
    while(p!=NULL)
    {
        printf("%d\n",p->data);
        p=p->next;
    }
}

//前向遍历
void priorEveryone(DNode *p)
{
    while (p->prior!=NULL)
    {
        printf("%d\n",p->data);
        p=p->prior;
    }
}

//尾插法(常用)
DLinkList List_InsertTail(DLinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    DNode *p=L;

    for(int i=1;i<=n;i++)
    {
        DNode *s=(DNode *) malloc(sizeof(DNode));
        s->data=i;
        s->next=NULL;
        s->prior=p;
        p->next=s;
        p=s;
    }
    return L;
}

//打印双链表
void printDLinkList(DLinkList L)
{
    DNode *p=L;
    while (p->next!=NULL)
    {
        p=p->next;
        printf("%d",p->data);
        printf("\n");
    }
}

int main()
{
    DLinkList L;
    L=InitDLinkList(L);
    L= List_InsertTail(L,6);
    

    //后向遍历
    printf("----------------------后向遍历----------------------\n");
    nextEveryone(L->next->next);
    //前向遍历(不包括头结点)
    printf("----------------------前向遍历----------------------\n");
    priorEveryone(L->next->next->next->next);

    return 0;
}

2.3、循环单链表

2.3.1、循环单链表的基本操作

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

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

//初始化循环单链表
LinkList InitLinkList(LinkList L)
{
    L=(LNode *) malloc(sizeof(LNode));
    if(L==NULL)
    {
        return NULL;
    }
    L->next=L;//循环单链表初始化的头指针的next指向自己
    return L;
}

//尾插法
LinkList List_InsertTail(LinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    LNode *p=L;
    for(int i=1;i<=n;i++)
    {
        LNode *s=(LNode *) malloc(sizeof(LNode));
        s->data=i;
        p->next=s;
        p=s;
    }
    p->next=L;
    return L;

}

//判断循环单链表是否为空
int LinkListEmpty(LinkList L)
{
    if(L->next==L)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

//打印循环单链表
void printLinkList(LinkList L)
{
    LNode *p=L;
    while (p->next!=L)
    {
        p=p->next;
        printf("%d\n",p->data);
    }
}

//判断结点是否为表尾结点
int isTail(LinkList L,LNode *p)
{
    if(p->next==L)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
//指定结点的后插操作
int InsertNextNode(LNode *p,int e)
{
    LNode *s=(LNode *) malloc(sizeof(LNode));
    if(s==NULL)
    {
        return 0;
    }
    s->data=e;
    s->next=p->next;
    p->next=s;
    return 1;
}

int main()
{
    LinkList L;
    L=InitLinkList(L);
    L=List_InsertTail(L,6);
    int flag= InsertNextNode(L->next->next,9999);
    if(flag==1)
    {
        printLinkList(L);
    }

    return 0;
}

2.4、循环双链表

2.4.1、循环双链表的基本操作

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"

typedef struct DLinkList{
    struct DLinkList *next;
    struct DLinkList *prior;
    int data;
}DNode,*DLinkList;


//初始化循环双链表
DLinkList InitDLinkList(DLinkList L)
{
    L=(DNode *) malloc(sizeof(DNode));
    if(L==NULL)
    {
        return NULL;
    }
    //初始化时,头结点的next指针和prior指针全部指自己
    L->next=L;
    L->prior=L;
    return L;
}

//打印双链表
void printDLinkList(DLinkList L)
{
    DNode *p=L;
    while (p->next!=L)
    {
        p=p->next;
        printf("%d",p->data);
        printf("\n");
    }
}

//判断循环双链表是否为空(判断头结点的next指针是否指向自己,也可判断头结点的prior指针是否指向自己)
/*
int DLinkListEmpty(DLinkList L)
{
    if(L->next==L)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
*/

//判断循环双链表是否为空链表(判断prior指针是否指向自己)
int DLinkListEmpty(DLinkList L)
{
    if(L->prior==L)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
//尾插法(常用)
DLinkList List_InsertTail(DLinkList L,int n)
{
    if(L==NULL)
    {
        return NULL;
    }
    DNode *p=L;

    for(int i=1;i<=n;i++)
    {
        DNode *s=(DNode *) malloc(sizeof(DNode));
        s->data=i;
        s->next=NULL;
        s->prior=p;
        p->next=s;
        p=s;
    }
    return L;
}

//判断当前结点是否为表尾结点
int isTail(DLinkList L,DNode *p)
{
    if(L==p)
    {
        return 0;
    }
    //1.p结点的next指针指向头结点,则p为表尾结点
    /*
    if(p->next==L)
    {
        return 1;
    }
    */
    //2.头结点L的prior指针指向p结点,则p为表尾结点
    if(L->prior==p)
    {
        return 1;
    }

}

//指定结点的后插操作
int InsertNextDNode(DNode *p,int e)
{
    if(p==NULL)
    {
        return 0;
    }
    DNode *s=(DNode *) malloc(sizeof(DNode));
    s->data=e;
    s->next=p->next;
    s->next->prior=s;
    s->prior=p;
    p->next=s;
    return 1;
}

int main()
{
    DLinkList L;
    L= InitDLinkList(L);
    L= List_InsertTail(L,8);
    int flag= InsertNextDNode(L->next->next->next,99999);
    if(flag==1)
    {
        printDLinkList(L);
    }

    return 0;

}



  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值