带表头结点的双向循环链表

本文介绍了如何操作带有表头结点的双向循环链表,包括创建链表、从头部、尾部和中间插入结点、删除指定数值的结点以及如何反转链表。提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


/*
=================
定义链表数据结构
=================
*/
struct node
{
    int num;
    struct node * next;
struct node * prior;
};


typedef struct node Node;
typedef struct node * Link;


/*
===============
功能:设头结点
返回:void
===============
*/ 
void creat_link(Link * head)
{
    (*head) = (Link)malloc(sizeof(Node)) ;  //创建一个新的节点,返回其地址
    if(NULL == (*head))
    {
        printf("malloc error!\n");
        exit(-1);
    }


    (*head) -> next = *head;
    (*head) -> prior = *head;


}
/*
=====================
功能:从头部插入结点
返回:void
=====================
*/ 


void insert_node_head(Link * head,Link new_node)
{
    Link tmp = *head;


    new_node->next = (*head)->next;
    (*head)->next->prior = new_node;
    new_node->prior = *head;
    (*head)->next = new_node;


    if((*head) -> prior == *head)
    {
        (*head)->prior = new_node;
    }
}
/*
=====================
功能:从尾部插入结点
返回:void
=====================
*/
void insert_node_tail(Link * head,Link new_node)
{
    Link tmp;
    tmp = *head;


    while(tmp->next != (*head)) // while(tmp != NULL)
    {                           // {
        tmp = tmp-> next;       //   tmp = tmp-> next;  此时已经已经指向NULL
    }                           // }


    tmp -> next = new_node;
    new_node -> next = *head;
    new_node -> prior = tmp;
    (*head) -> prior = new_node;
    /* 更好的写法 */
    //head->prior->next = newnode; 
    //newnode->prior = head->prior; 
    //newnode->next = head; 
    //head->prior = newnode;   
}




void insert_node_mid(Link * head,Link new_node,int num)    //插入节点
{
    Link  tmp = (*head)->next; 


    if(*head == (*head)->next)
    {
        printf("link is empty !\n");
        return;
    }
    else
    {
while(tmp -> num != num && tmp -> next != (*head)) //找到要插入的位置
        {
            tmp = tmp -> next;
        }


        if(tmp -> num == num)  //判断这个位置是否为真的节点
        {
            new_node -> next = tmp -> next;
            new_node -> prior = tmp ;
            tmp -> next -> prior = new_node;
            tmp ->next = new_node;
        }
        else
        {
            printf("no such node!\n");
        }
    }
}


void delete_node(Link * head,int num_delete)
{
    Link tmp = (*head)->next;
    Link p   = NULL;


    if((*head) == tmp)
    {
        printf("link is empty !\n");
        return;
    }
    else
    {
        while(tmp -> num != num_delete && tmp -> next != NULL)
        {
            p   = tmp;      //需要一个指针用于跟踪
            tmp = tmp -> next;
        }


        if(tmp -> num == num_delete) //找到这个位置
        {
            /*if( tmp == (*head)->next)
            {  
                tmp -> next -> prior = (*head);
                (*head) -> next = tmp -> next;
                free(tmp);
            }
            else if(tmp -> next == (*head))
            {
                p -> next = (*head);
                (*head) -> prior = p;
                free(tmp);
            }
            else
            {
                tmp -> next -> prior = p;
                p -> next =  tmp -> next;
                free(tmp);
            }*/
               tmp->prior->next = tmp->next; 
            tmp->next->prior = tmp->prior; 


            free(tmp);         //释放 
            tmp = NULL;        //置空 
        }
        else
        {
            printf("no such node!\n");
        }
    }
}
void revers_link(Link * head)
{
    Link p1,p2,p3;
    Link tmp  = (*head)->next;


    if((*head) -> next == (*head)) return;


    else if((*head) -> next -> next == (*head))
    {
        (*head) -> next = tmp -> next;
        tmp -> next -> next= tmp;
        tmp -> next = (*head);


        return;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值