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

来源:互联网 发布:女士围巾推荐 知乎 编辑:程序博客网 时间:2024/05/17 02:51
/*****************************************************
Funcion List: 
        实现带表头节点的双向链表的
        头插,尾插,中间插,倒序,释放
*****************************************************/


#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;
    }


    else
    {
        p3 = tmp;
        p2 = p3 -> next;
        p1 = p2 -> next;
        while(p1 -> next != (*head))
        {
            p2 -> next = p3;
            p2 -> prior = p1;
            p3 = p2;
            p2 = p1;
            p1 = p1->next;
        }
        p2 -> next = p3;
        p2 -> prior = p1;
        p1 -> next = p2;
        p1 -> prior = (*head);
        (*head) -> next -> next = (*head);
        (*head) -> next = p1;
    }
}




void free_node(Link * head)
{
    Link tmp = (*head)->next;
    Link p   = *head;


    if( tmp == (*head))
    {
        printf("link is emtpy\n");
        return;
    }


    while(  (*head)->next != (*head))
    {   
        tmp = (*head)->next;
        (*head) ->next = tmp -> next;
        (*head) ->next -> prior = (*head);
        free(tmp);
    }


    /*仍然需要构成环*/
    (*head) -> next = (*head);
    (*head) -> prior = (*head);
    printf("Link is freed\n");
}


void display(Link head)
{
    Link tmp;
    tmp = head -> next;


    if(head == head -> next)
    {
        printf("Link is empty\n");
    }


    while(tmp != head)
    {
        printf("num = %d\n",tmp->num);
        tmp = tmp -> next;
    }
}


int main()
{
    Link head = NULL;
    Link new_node = NULL;
    int i;
    int num_insert,num_delete;


    creat_link(&head);   //创建用于指向表头结点的Link型指针(头指针),此时指向NULL。


    for(i = 0; i <10; i++)
    {
        new_node = (Link)malloc(sizeof(Node)) ;  //创建一个新的节点,返回其地址
        if(NULL == new_node)
        {
            printf("malloc error!\n");
            exit(-1);
        }
        new_node -> num = i;  //节点赋值


        insert_node_head(&head,new_node);    //插入节点
    //  insert_node(&head,new_node,new_node->num);    
    //  insert_node_tail(&head,new_node);    //插入节点(尾插)
    }


    display(head);
    printf("请输入要插入的序号:");
    scanf("%d",&num_insert);


    new_node = (Link)malloc(sizeof(Node)) ;  //创建一个新的节点,返回其地址


    if(NULL == new_node)
    {
        printf("malloc error!\n");
        exit(-1);       
    }


    new_node -> num = 321;  //节点赋值


    insert_node_mid(&head,new_node,num_insert);    //插入节点(中间)
    display(head);


    printf("请输入要删除的序号:");
    scanf("%d",&num_delete);


    delete_node(&head,num_delete);
    display(head);
    printf("------------\n");


    revers_link(&head);
    display(head);
    printf("------------\n");


    free_node(&head);
    printf("------------\n");


    display(head);
    printf("------------\n");


    return 0;
}

0 0
原创粉丝点击