双向循环链表函数(有删除,增加,排序,统计等功能)

来源:互联网 发布:沈阳有几种打车软件 编辑:程序博客网 时间:2024/06/05 06:39
#include<stdio.h>
#include<stdlib.h>

struct node
{
    int num;
    char name[20];
    struct node *next;
    struct node *prior;
};

typedef struct node Node;
typedef struct node *Link;

void is_malloc_ok(Link new_node)
{
    if (new_node == NULL)
        exit(-1);
}
void create_new_node(Link *new_node)
{
    *new_node = (Link)malloc(sizeof(Node));
  
    is_malloc_ok(*new_node);
}

void create_bilateral_cycle(Link *head)  //带表头的双向循环链表,链表中只有表头,表头的前驱和后继都是本身
{
    create_new_node (head);
    (*head)->prior = *head;
    (*head)->next = *head;
}
void insert_node_head(Link head, Link new_node)  // 头插,每一次插入把结点作为表头的直接后继,
{
    Link p;
    p = head;

    new_node->prior = p;
    new_node->next = p->next;
    p->next->prior = new_node;
    p->next = new_node;
   
}

void insert_node_tail(Link head, Link new_node)  //尾插,每一次插入把结点作为表头的直接前驱
{
    Link p;
    p = head;

    new_node->prior = p->prior;
    new_node->next = p;
    p->prior->next = new_node;
    p->prior = new_node;
}


void display_forward (Link head)  //输出函数:从表头的直接后继开始输出
{
    Link p;
    p = head->next;

    if (p == head)
    {
        printf("The link is empty!");
        return;
    }
    while (p != head)
    {
        printf("%4d: %s\n",p->num,p->name);
 p = p->next;
    }
}
 
void display_backward (Link head)  //输出函数:从表头的直接前驱开始输出
{
    Link p;
    p = head->prior;
    if (p == head)
    {
        printf("The link is empty!");
 return;
    }
    while (p != head)
    {
        printf("%4d: %s\n",p->num,p->name);
        p = p->prior;
    }
}

int count (Link head)   //计数函数:计算除了表头外所有的结点数
{
    int n = 0;
    Link p;
    p = head->next;
   
    while ( p != head)
    {
        n++;
 p = p->next;
    }
    return n;
}

Link search (Link head, int n)  //搜索函数:输入结点中成员num的值,返回成员所在结点的地址
{
    Link p;
    p = head->next;
 
    while ( p != head )
    {
        if (p->num == n)
        {
     break;
 }
 p = p->next;
    }

    return p;
}
void delete_node (Link head, int n) //删除函数:输入结点中num的值,删除成员所在结点
{
    Link p;
    p = search (head,n);
   
    if (p == head)
    {
        printf("没有这个值!");
 return;
    }
   
    p->next->prior = p->prior;
    p->prior->next = p->next;
    free(p);
   

}

void insert_sort(Link head, Link new_node)  //边排边插函数,将结点有序的插在链表中
{
    Link p;
    p = head->prior;
    int number = new_node->num;
   
    if (p == head)
    {
        head->next = new_node;
 head->prior = new_node;
 new_node->next = head;
 new_node->prior = head;
    }
    else if (number <= p->num)
    {
 new_node->next = head;
 new_node->prior = head->prior;
 head->prior->next = new_node;
        head->prior = new_node;
    }
    else if (number >= head->next->num)
    {
        new_node->prior = head;
 new_node->next = head->next;
 head->next->prior = new_node;
        head->next = new_node;   
    }
    else
    {
        while ( p != head)
        {
     if (number <= p->num)
     {
         new_node->prior = p;
  new_node->next = p->next;
  p->next->prior = new_node;
  p->next = new_node;
  break;
     }

     p = p->prior;
 }
    }
}

void plus_node(Link head, int n)   //增加结点函数:输入成员中num的值,将结点放在该成员所在结点的前面
{
    Link new_node;
    Link p;
    p = search(head,n);
   
    create_new_node(&new_node);
  
   if (p = head)
    {
        printf("Fail!");
 return ;
    }
  
    printf("输入新结点的num值");
    scanf("%d",&new_node->num);
    printf("输入新结点的name值");
    scanf("%s",new_node->name);
    new_node->next = p;
    new_node->prior = p->prior;
    p->prior->next = new_node;
    p->prior = new_node;

}
void release (Link *head)    //释放函数:释放所有的空间
{
    Link p;
    p = (*head)->prior;
   
    if (p == *head)
    {
        free(p);
 return;
    }
    while (p != *head)
    {
       (*head)->prior = p->prior;
        p->prior->next = *head;
 free(p);
 p = (*head)->prior;
    }

}
int main()
{
    Link head = NULL;
    Link new_node = NULL;
    int i;
    int n;

    create_bilateral_cycle(&head);
   
    for(i = 1; i < 3; i++)
    {
        create_new_node(&new_node);
       
 new_node->num = i;
 printf("输入第%d个人的名字",i);

        scanf("%s",new_node->name);

       insert_node_head(head,new_node);

// insert_node_tail(head,new_node);
    }
   
    display_forward(head);

    printf("此链表有%d个结点。",count(head));

    printf("输入结点中num值,删除此结点:");
    scanf("%d",&n);
    delete_node (head,n);
    display_forward(head);

    printf("输入结点中num值,在前面加一个结点:");
    scanf("%d",&n);
    plus_node(head,n);
    display_forward(head);


    for (i = 1; i < 3; i++)
    {
        create_new_node(&new_node);
        printf("输入插入的第%d个结点的值:",i);
 scanf("%d",&new_node->num);
        printf("输入插入的第%d个结点的名字:",i);
 scanf("%s",new_node->name);

 insert_sort(head,new_node);
    }

    display_backward(head);
   
    release(&head);
    display_backward(head);





    return 0;
}
0 0
原创粉丝点击