C语言单链表,双向链表,循环单链表,循环双链表的基本操作

1.单链表的基本操作(C语言)

创建头节点


Linklist *Creat(Linklist *L)
{
    L = (Linklist *)malloc(sizeof(Linklist));
    if (L == NULL)   return NULL;   /*内存分配不成功,返回空指针*/
    L -> next = NULL;
    return L;
}


插入一个新的节点

先用malloc函数给新的节点开辟空间然后具体插入如下图所示


head -> next = t;
p -> next = q;

删除一个节点





p = L;
q = p -> next;
while(q!= NULL)
{
       if(num2 == n)
        {
                p -> next = q -> next;
                return 1;
        }
        else
        {
                num2++;
                p = p -> next;
                q = p -> next;
        }

     }

具体代码如下所示:

              /*双链表的基本操作,输入输出,插入,删除*/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
    int data;
    struct node *next;
}Linklist;
Linklist *Creat(Linklist *L)
{
    L = (Linklist *)malloc(sizeof(Linklist));
    if (L == NULL)   return NULL;   /*内存分配不成功,返回空指针*/
    L -> next = NULL;
    return L;
}
void Input(Linklist *head)
{
    int x;    //用来存放节点的值域
    Linklist *r,*p;
    r = head;
    scanf("%d",&x);
    while(x != -1)   //-1作为链表的终止信号
    {
        p = (Linklist *)malloc(sizeof(Linklist));
        p -> data = x;
        p -> next = NULL;
        r -> next = p;
        r = r -> next;
        scanf("%d",&x);
    }
}
void Output(Linklist *L)
{
    Linklist *q;
    for(q = L -> next;q != NULL;q = q -> next)
    {
        printf("%d ",q -> data);
    }
}
int Insert(Linklist *L,int m)    //按照给定节点插入,前插法(后插法类似于前插法)
{
    int item,num1 = 1;         //表示新插入节点的值域
	Linklist *t,*p,*q;            //t表示新插入的节点
	scanf("%d",&item);
	t = (Linklist *)malloc(sizeof(Linklist));  //为插入的节点开辟空间
	t -> data = item;
	if(L -> next == NULL)    //链表是空表的情况下   L是头结点
	{
	    if(m == 1)           //当插入的位置刚好是第一个位置时
        {
            L -> next = t;
            t -> next = NULL;
            return 1;    //1表示成功插入,0表示插入失败
        }
        else
        {
            printf("The position of Insert is incorrect\n");
            return 0;
        }
	}
	else       //链表不是空表的情况下
    {
        p = L;
        q = p -> next;
        while(q != NULL)
        {
            if(num1 == m)
            {
                /*当指针q指向第m个节点时,插入节点t
                 * 将节点t插到第m个节点之前
                 */
                p -> next = t;
                t -> next = q;
                return 1;
            }
            else
            {
                num1++;
                p = p -> next;
                q = p -> next;
            }

        }

    }
    if(q == NULL)
    {
        printf("The inserted node does not exist\n");
        return 0;
    }

}
int Delete(Linklist *L,int n)   //按照指定节点删除
{
    int num2 = 1;
    Linklist *p,*q;
    if(n < 0)
    {
        printf("Error\n");
        return 0;
    }
    if(L -> next == NULL)
    {
        printf("The List is empty\n");  //空表的话,删除失败
        return 0;                            //0表示删除成功,1表示删除成功
    }
    else
    {
        p = L;
        q = p -> next;
        while(q!= NULL)
        {
            if(num2 == n)
            {
                p -> next = q -> next;
                return 1;
            }
            else
            {
                num2++;
                p = p -> next;
                q = p -> next;
            }

        }
    }
    if(q == NULL)
    {
        printf("The inserted node does not exist\n");
        return 0;
    }

}

int main()
{
    Linklist List;
    Input(&List);
    Output(&List);
    //Insert(&List,4);
    //Output(&List);
    Delete(&List,3);
    printf("\n");
    Output(&List);
    return 0;
}
后面几种链表都是在单链表上的延伸

双向链表的基本操作

              /*双向链表的基本操作,输入输出,插入,删除*/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
    int data;
    struct node *next,*prior;
}DoubleLinklist;
DoubleLinklist *Creat(DoubleLinklist *L)
{
    L = (DoubleLinklist *)malloc(sizeof(DoubleLinklist));
    if (L == NULL)   return NULL;   /*内存分配不成功,返回空指针*/
    L -> next = NULL;
    L -> prior = NULL;
    return L;
}
void Input(DoubleLinklist *head)
{
    int x;    //用来存放节点的值域
    DoubleLinklist *r,*p;
    r = head;
    scanf("%d",&x);
    while(x != -1)   //-1作为链表的终止信号
    {
        p = (DoubleLinklist *)malloc(sizeof(DoubleLinklist));
        p -> data = x;
        p -> next = NULL;
        p -> prior = r;
        r -> next = p;
        r = r -> next;
        scanf("%d",&x);
    }
}
void Output(DoubleLinklist *L)
{
    DoubleLinklist *q;
    for(q = L -> next;q != NULL;q = q -> next)
    {
        printf("%d ",q -> data);
    }
}
int Insert(DoubleLinklist *L,int m)    //按照给定节点插入,前插法(后插法类似于前插法)
{
    int item,num1 = 0;         //表示新插入节点的值域
	DoubleLinklist *t,*p;            //表示新插入的节点
	scanf("%d",&item);
	t = (DoubleLinklist *)malloc(sizeof(DoubleLinklist));  //为插入的节点开辟空间
	t -> data = item;
	if(L -> next == NULL)    //链表是空表的情况下   L是头结点
	{
	    if(m == 1)           //当插入的位置刚好是第一个位置时
        {
            L -> next = t;
            t -> next = NULL;
            t -> prior = L;
            return 1;    //1表示成功插入,0表示插入失败
        }
        else
        {
            printf("The position of Insert is incorrect\n");
            return 0;
        }
	}
	else       //链表不是空表的情况下
    {
        p = L;
        while(p != NULL)
        {
            if(num1 == m)
            {
                /*当指针p指向第m个节点时,插入节点t
                 * 将节点t插到第m个节点之前
                 */
                t -> next = p;
                t -> prior = p -> prior;
                p -> prior -> next = t;
                p -> prior = t;
                return 1;
            }
            else
            {
                num1++;
                p = p -> next;
            }

        }

    }
    if(p == NULL)
    {
        printf("The inserted node does not exist\n");
        return 0;
    }

}
int Delete(DoubleLinklist *L,int n)   //按照指定节点删除
{
    int num2 = 0;
    DoubleLinklist *p;
    if(n < 0)
    {
        printf("Error\n");
        return 0;
    }
    if(L -> next == NULL)
    {
        printf("The List is empty\n");  //空表的话,删除失败
        return 0;                            //0表示删除成功,1表示删除成功
    }
    else
    {
        p = L;
        while(p -> next != NULL)
        {
            if(num2 == n)
            {
                /*当找到第n个节点(非尾节点)时,将其删除*/
                p -> prior -> next = p -> next;
                p -> next -> prior = p -> prior;
                return 1;
            }
            else
            {
                num2++;
                p = p -> next;
            }

        }
    }
    if(p -> next == NULL && num2 == n)  /*删除的是最后一个节点*/
    {
        p -> prior -> next = NULL;
        free(p);
        return 1;
    }
    else
    {
        printf("\nThe delete node does not exist\n");
        return 0;
    }
}
/*BUG已经解决*/
/*删除节点的BUG在于无法删除最后一个节点和无法输出wrong的情况*/
int main()
{
    void Input(DoubleLinklist *head);
    void Output(DoubleLinklist *L);
    DoubleLinklist List;
    Input(&List);
    Output(&List);
    //Insert(&List,3);
    //Output(&List);
    Delete(&List,6);
    printf("\n");
    Output(&List);
    return 0;
}


 

  循环单链表的基本操作    

              /*循环链表的基本操作,输入输出,插入,删除*/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
    int data;
    struct node *next;
}Circularlist;
Circularlist *Creat(Circularlist *L)
{
    L = (Circularlist *)malloc(sizeof(Circularlist));
    if (L == NULL)   return NULL;   /*内存分配不成功,返回空指针*/
    L -> next = NULL;
    return L;
}
void Input(Circularlist *head)
{
    int x;    //用来存放节点的值域
    Circularlist *r,*p;
    r = head;
    scanf("%d",&x);
    while(x != -1)   //-1作为链表的终止信号
    {
        p = (Circularlist *)malloc(sizeof(Circularlist));
        p -> data = x;
        p -> next = head;
        r -> next = p;
        r = r -> next;
        scanf("%d",&x);
    }
}
void Output(Circularlist *L)
{
    Circularlist *q;
    for(q = L -> next;q != L;q = q -> next)
    {
        printf("%d ",q -> data);
    }
}
int Insert(Circularlist *L,int m)    //按照给定节点插入,前插法(后插法类似于前插法)
{
    int item,num1 = 0;         //表示新插入节点的值域
	Circularlist *t,*p;            //表示新插入的节点
	scanf("%d",&item);
	t = (Circularlist *)malloc(sizeof(Circularlist));  //为插入的节点开辟空间
	t -> data = item;
	if(L -> next == L)    //链表是空表的情况下   L是头结点
	{
	    if(m == 1)           //当插入的位置刚好是第一个位置时
        {
            L -> next = t;
            t -> next = L;
            return 1;    //1表示成功插入,0表示插入失败
        }
        else
        {
            printf("The position of Insert is incorrect\n");
            return 0;
        }
	}
	else       //链表不是空表的情况下
    {
        p = L;
        while(p -> next != L)
        {
            if(num1 + 1 == m)
            {
                /*当指针p指向第m - 1个节点时,插入节点t(不是第一个节点)
                 * 将节点t插到第m - 1个节点之后,第m个节点之前
                 */
                /*由于单链表没有前驱指针,所以前插法的话只能找到待插入节点的前一个节点时,
                  *插入待插入的节点(当然也可以再声明一个指针)
                  */
                t -> next = p -> next;
                p -> next = t;
                return 1;
            }
            else
            {
                num1++;
                p = p -> next;
            }

        }

    }

}
int Delete(Circularlist *L,int n)   //按照指定节点删除
{
    int num2 = 1;
    Circularlist *p,*q;
    if(n < 0)
    {
        printf("Error\n");
        return 0;
    }
    if(L -> next == NULL)
    {
        printf("The List is empty\n");  //空表的话,删除失败
        return 0;                            //0表示删除成功,1表示删除成功
    }
    else
    {
        q = L;
        p = q -> next;
        while(q -> next != L)
        {
            if(num2 == n)
            {
                /*当找到第n个节点(非尾节点)时,将其后一个节点删除(利用循环链表的特性)*/
                q -> next = p -> next;
                return 1;
            }
            else
            {
                num2++;
                q = q -> next;
                p = q -> next;
            }

        }
    }
    printf("\nThe delete node does not exist\n");
    return 0;

}
/*删除节点的BUG在于无法删除最后一个节点和无法输出wrong的情况*/
int main()
{
    void Input(Circularlist *head);
    void Output(Circularlist *L);
    Circularlist List;
    Input(&List);
    Output(&List);
    //Insert(&List,6);
    //Output(&List);
    Delete(&List,1);
    printf("\n");
    Output(&List);
    return 0;
}

循环双链表的基本操作

              /*双链表的基本操作,输入输出,插入,删除,查找*/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
    int data;
    struct node *next,*prior;
}DoubleCircularLinklist;
DoubleCircularLinklist *Creat(DoubleCircularLinklist *L)
{
    L = (DoubleCircularLinklist *)malloc(sizeof(DoubleCircularLinklist));
    if (L == NULL)   return NULL;   /*内存分配不成功,返回空指针*/
    L -> next = NULL;
    L -> prior = NULL;
    return L;
}
void Input(DoubleCircularLinklist *head)
{
    int x;    //用来存放节点的值域
    DoubleCircularLinklist *r,*p;
    r = head;
    scanf("%d",&x);
    while(x != -1)   //-1作为链表的终止信号
    {
        p = (DoubleCircularLinklist *)malloc(sizeof(DoubleCircularLinklist));
        p -> data = x;
        p -> next = head;
        p -> prior = r;
        r -> next = p;
        r = r -> next;
        scanf("%d",&x);
    }
}
void Output(DoubleCircularLinklist *L)
{
    DoubleCircularLinklist *q;
    for(q = L -> next;q != L;q = q -> next)
    {
        printf("%d ",q -> data);
    }
}
int Insert(DoubleCircularLinklist *L,int m)    //按照给定节点插入,前插法(后插法类似于前插法)
{
    int item,num1 = 1;         //item表示新插入节点的值域
	DoubleCircularLinklist *t,*p,*q;
	scanf("%d",&item);
	t = (DoubleCircularLinklist *)malloc(sizeof(DoubleCircularLinklist));  //为插入的节点开辟空间
	t -> data = item;
	if(L -> next == L)    //链表是空表的情况下   L是头结点
	{
	    if(m == 1)           //当插入的位置刚好是第一个位置时
        {
            L -> next = t;
            t -> next = L;
            t -> prior = L;
            return 1;    //1表示成功插入,0表示插入失败
        }
        else
        {
            printf("The position of Insert is incorrect\n");
            return 0;
        }
	}
	else       //链表不是空表的情况下
    {
        p = L;
        q = p -> next;
        while(p -> next != L)
        {
            if(num1 == m)
            {
                /*当指针q指向第m个节点时,插入节点t
                 * 将节点t插到第m个节点之前
                 */
                p -> next = t;
                t -> prior = p;
                t -> next = q;
                q -> prior = t;
                return 1;
            }
            else
            {
                num1++;
                p = p -> next;
                q = p -> next;
            }

        }

    }
    if(p -> next == L)
    {
        printf("The inserted node does not exist\n");
        return 0;
    }

}
int Delete(DoubleCircularLinklist *L,int n)   //按照指定节点删除
{
    int num2 = 1;
    DoubleCircularLinklist *p,*q;
    if(n < 0)
    {
        printf("Error\n");
        return 0;
    }
    if(L -> next == L)
    {
        printf("The List is empty\n");  //空表的话,删除失败
        return 0;                            //0表示删除成功,1表示删除成功
    }
    else
    {
        p = L;
        q = L -> next;
        while(p -> next != L)
        {
            if(num2 == n)
            {
                /*当找到第n个节点时,将其删除*/
                p -> next = q -> next;
                q -> next -> prior = p;
                return 1;
            }
            else
            {
                num2++;
                p = p -> next;
                q = p -> next;
            }

        }
    }
    if(p -> next == L)
    {
        printf("\nThe delete node does not exist\n");
        return 0;
    }

}
/*BUG已经解决*/
/*删除节点的BUG在于无法删除最后一个节点和无法输出wrong的情况*/
int main()
{
    void Input(DoubleCircularLinklist *head);
    void Output(DoubleCircularLinklist *L);
    DoubleCircularLinklist List;
    Input(&List);
    Output(&List);
    //Insert(&List,6);
    //Output(&List);
    Delete(&List,1);
    printf("\n");
    Output(&List);
    return 0;
}


有不足的地方还望指教。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值