zoukankan      html  css  js  c++  java
  • 双向循环链表的简单操作

        最近看了linux内核代码list.h发现大部分都是链表的一些操作,所以就把双向循环链表的一些简单操作写了写,结果发现什么东西还是要经常练,不然就生疏了;主要实现了双向链表的增、删、改、查、排序、及双向遍历。
    源码如下:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<malloc.h>

    typedef struct student
    {
      int id;
      char name[20];
      struct student *pre,*next;
    }stu,*linklist;

    void init(linklist *head)      //初始化头结点
    {
      (*head)=(linklist)malloc(sizeof(stu));
      printf("please input the first student`s id:\n");
      scanf("%d",&(*head)->id);
      printf("please input the first student`s name:\n");
      scanf("%s",(*head)->name);

      (*head)->pre=*head;
      (*head)->next=*head;
    }

    linklist del(linklist head,int id)  //按学号删除一个节点
    {
      stu *p=head;
      if (id == head->id)
      {
         printf("the entry you del is the head\n");
         head->pre->next = head->next;
         head->next->pre = head->pre;
         head = head->next;
      }
      else
      {
        while (id != p->id)
           p = p->next;

        p->pre->next = p->next;
        p->next->pre = p->pre;
      }

      free(p);
      return head;   //必须返回头节点,否则删除头结点后,不能正常遍历链表
    }

    void add_entry(linklist head)    //头插法添加一个节点
    {
      stu *new;
      new=(stu *)malloc(sizeof(stu));
      printf("please input id\n");
      scanf("%d",&new->id);
      printf("please input name:\n");
      scanf("%s",new->name);

      new->next = head->next;
      new->pre = head->next->pre;
      head->next->pre = new;
      head->next = new;
    }

    void add_entry_tail(linklist head)  //尾插法添加一个节点
    {
      stu *new,*p = head;
      new=(stu *)malloc(sizeof(stu));
      printf("please input id\n");
      scanf("%d",&new->id);
      printf("please input name:\n");
      scanf("%s",new->name);

      while (p->next != head)
          p = p->next;
     
      new->next = head;
      head->pre = new;
      new->pre = p;
      p->next = new;
    }

    int  change(linklist head,int id)   //修改学号为id的学生的信息
    {
      stu *p=head;

      while (p->id != id)
      {
         p = p->next;
         if (p == head)
         {
           printf("there is no student you want to change the info:\n");
           return 0;
         }
      }
      printf("please input new id and name:\n");
      scanf("%d%s",&p->id,p->name);
      return 1;
    }
    void swap(stu *p,stu *q)        //交换p和q两个节点的数据,用于排序
    {
      int id1;
      char name1[20];

      id1=p->id;
      p->id=q->id;
      q->id=id1;

      strcpy(name1,p->name);
      strcpy(p->name,q->name);
      strcpy(q->name,name1);
    }

    void sort_id(linklist head)   //按学号排序
    {
      stu *p=head,*q;

      while (p->next != head)
      {
        q = p->next;

        while (q != head)
        {
         if((p->id) > (q->id))
            swap(p,q);
         q=q->next;
        }

        p=p->next;
      }
    }

    int find_id(linklist head,int id)    //按学号查找
    {
       stu *p=head;

       while (p->id != id)
       {
         p = p->next;
         if (p == head)
         {
           printf("no found the student\n");
           return 0;
         }
       }

       printf("\nthe info of the student is:\n");
       printf("id   is :%d\n",p->id);
       printf("name is :%s\n",p->name);
       return 1;
    }

    int find_name(linklist head,char name[])     //按姓名查找
    {
       stu *p=head;
       int flag=0;
       /*无重名情况下如下编写即可
       while(strcmp(p->name,name)!=0)
       {
         p=p->next;
         if(p==head)
         {
            printf("no found the student\n");
            return 0;
         }
       }
       printf("\nthe info of the student is:\n");
       printf("id   is :%d\n",p->id);
       printf("name is :%s\n",p->name);
       return 1;          */
       //为防止有重名情况不能将所有学生信息查到,如下处理
       do
       {
          if (strcmp(p->name,name) == 0)
          {
            printf("\nthe info of the student is:\n");
            printf("id   is :%d\n",p->id);
            printf("name is :%s\n",p->name);
            flag=1;
          }
          p=p->next;
       }while (p != head);

       if(flag==0)
       {
          printf("no found the student\n");
          return 0;
       }
       return 1;
    }

    void list_for_each(linklist head)   //遍历每个节点并打印出信息,按next顺序
    {
      stu *p=head;
      printf("************************************************\n");
      do
      {
         printf("%d   %s\n",p->id,p->name);
         p = p->next;
      }while (p != head);
    }

    void list_for_each_pre(linklist head)  //遍历每个节点并打印出信息,按pre顺序
    {
      stu *p = head->pre,*q = head->pre;
      printf("**************************************************\n");
      do
      {
         printf("%d   %s\n",p->id,p->name);
         p = p->pre;
      }while (p != q);
    }

    linklist add_entry_aftersort(linklist head) //排序后添加一个节点到合适的位置,使链表仍然按学号有序
    {
      stu *new,*p=head;
      new=(stu *)malloc(sizeof(stu));
      printf("add entry after sort----");
      printf("please input id\n");
      scanf("%d",&new->id);
      printf("please input name:\n");
      scanf("%s",new->name);

      do
      {
         if ((new->id > p->id) && (new->id < p->next->id))
         {
            new->next = p->next;
            new->pre = p;
            p->next->pre = new;
            p->next = new;
            break;
         }

         p = p->next;
      }while (p != head);

      if (p == head)
      {
         new->next = p;
         new->pre = p->pre;
         p->pre->next = new;
         p->pre = new;
         if ((new->id) <= (head->id))
           head = new;
      }
      return head;
    }
    int main()
    {
       linklist  head;
       int id;
       char name[20];
       init(&head);

       add_entry(head);
       add_entry(head);
       add_entry_tail(head);
       list_for_each(head);

       printf("please input the id you want to del:\n");
       scanf("%d",&id);
       head=del(head,id);
       list_for_each_pre(head);

       printf("please input the id you want to change:\n");
       scanf("%d",&id);
       change(head,id);
       list_for_each(head);

       sort_id(head);
       printf("\n顺序打印:\n");
       list_for_each(head);
       printf("\n逆序打印:\n");
       list_for_each_pre(head);

       head=add_entry_aftersort(head);
       list_for_each(head);

       printf("please input the id you want to search:\n");
       scanf("%d",&id);
       find_id(head,id);

       printf("please input the name you want to search:\n");
       scanf("%s",name);
       find_name(head,name);

       return 0;
    }
    这里只是一些简单的操作,如果要做成一个比较完善的系统,还有很多地方要修改,不过基本的功能基本上都实现。

  • 相关阅读:
    类似Sina新浪滑动门代码
    纯CSS无JS实现灰色下拉导航菜单代码
    滑动门与选项卡互转的实现方法代码
    一款横向、竖向两个选项卡Tab一起联动的导航代码
    C#Brush的使用(转载)
    泛型学习笔记(转载)
    Application之间共享MasterPage(转载)
    ReportView学习笔记一(转载)
    BackGroundWorker学习
    加下划线的TextBox
  • 原文地址:https://www.cnblogs.com/276815076/p/1814975.html
Copyright © 2011-2022 走看看