双向链表_

http://lvguohaolcj.blog.163.com/blog/static/31646731201073121340250/

一、循环链表

       循环链表是与单链表一样,是一种链式的存储结构,所不同的是,循环链表

       的最后一个结点的指针是指向该循环链表的第一个结点或者表头结点,从而

       构成一个环形的链;

  循环链表和单链表的运算不同点:

  1、在建立一个循环链表时,必须使其最好一个结点的指针指向表头结点,而

  不是象单链表那样置为NULL,此中情况还使用于在最后一个结点后插入一个

  新的结点;

  2、在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值

  等于表头指针时,说明已经表尾,而非象单链表那样判断链域值是否为NULL

  二、双向链表

              当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,

  又必须从表表头开始查找。这是由单链表结点的结构所限制的,因为单链表每个

  结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接

  后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点

  结构呢?这就是双向链表。

              在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继

  结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。

*/

//双向链表

typedef struct node

{

       char name[20];

       struct node *llink,*rlink;

}stud;

stud* creat(int n)

{

       stud *p,*h,*s;

       

       int size = sizeof(stud);

       if ((h= (stud*) malloc(size)) == NULL)

       {

              printf("malloc failt");

              exit(0);

       }

       //创建一个空的结构指针空间;

       h->name[0] = '\0';

       h->llink = NULL;

       h->rlink =NULL;

       p = h;

       for (int i=0;i<n;i++)

       {

              if ((s = (stud*) malloc(size)) == NULL)

              {

                     printf("malloc failt");

                     exit(0);

              }

              p->rlink = s;

              printf("请输入第%d个人的姓名",n+1);

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

              s->llink = p;

              s->rlink = NULL;

              s= p;

       }

       h->llink =s;

       p->rlink = h;

       return (h);

}

/*

假若我们要在一个表头的双向循环链表中查找数据域为一特定值的某个结点时,

我们同样从表头结点往后一次比较各结点数据域的值,若正是该特定值,则返

回指向结点的指针,否则继续往后查,直到表尾。

*/

stud* seach(stud *h,char* x)

{

       stud *p;

       char *y;

       p = h->rlink;

       while(p != h)

       {

              y = p->name;

              if (strcmp(y,x) == 0)

              {

                     return (p);

              }

              else

              {

                     p= p->rlink;

              }

       }

       

       printf("没有查找到该数据");

}

void print(stud *h)

{

       stud *p;   

       p = h->rlink;

       

       printf("数据信息为:\n");

       while(p != h)

       {

              printf("%s ",&*(p->name));

              p=p->rlink;

       }

       printf("\n");

}

/*

对于双向链表,我们可以随意在某个结点前或后插入一个新的结点;

假诺spq是连续三个结点的指针,若我们要p前插入一个新结点r

则只需把s的右链域指针指向rr的左链域指针指向sr的右链域指针指向

pp的左链域指针指向r即可。

*/

void insert(stud* p)

{

       char stuname[20];

       stud *s;

       if ((s= (stud*)malloc(sizeof(stud))) ==NULL)

       {

              printf("malloc Fail");

              exit(0);

       }

       printf("请插入人的姓名:");

       scanf("%s",stuname);

       strcpy(s->name,stuname);

       s->rlink = p->rlink;

       p->rlink = s;

       s->llink = p;

       (s->rlink)->llink =s;

}

/*

 删除某个结点,其实就是插入某个结点的逆操作,还是对于双向循环,要在连续三个结点

 spq中删除p点,只需把s的右链域指针指向qq的左链域指针指向s,并回收p结点。

*/

void del(stud *p)

{

       (p->rlink)->llink = p->llink;

       (p->llink)->rlink = p->rlink;

       free(p);

}

C语言实现双向链表

2009年03月23日 星期一 下午 03:34

/************双向链表*******/
#include <stdio.h>
#include <conio.h>

typedef struct LIST
{
int element;
        struct LIST *prior;
struct LIST *next;
}LIST;

LIST *Init_List            (void);           /** 建表 **/
int       Insert_List       (LIST *List, int i, int element); /** 插入元素 **/
int      Delect_List      (LIST *List, int i);      /** 删除元素 **/
LIST *Get_piout        (LIST *List, int i);
void   List_List          (LIST *List);           /** 打印表 **/
char   menu               (void);

int main (void)
{
       int i;
         int element;
       LIST *List;
        char choice;

       List = Init_List ();

        do
        {
                choice = menu ();
           
                switch (choice)
                {
                     case 'i':
                       case 'I':
                               printf ("i , element==>> ");
                                scanf ("%d%d", &i, &element); 
                               Insert_List (List, i, element);
                               break;
           
                       case 'd':
                        case 'D':
                                printf ("i==>> ");
                                scanf ("%d", &i);
                               Delect_List (List, i);  
                               break;
    
                       case 'l':
                       case 'L':
                                 List_List (List);
                                 break;
    
                        default :
                                 break;
                 }
       }while (choice != 'q' && choice != 'Q');

      return 0;
}
  
/**建表**/
LIST *Init_List (void)
{
      int i ;
      LIST *temp, *This, *List;

      List = (LIST *) malloc (sizeof(LIST));
      List->prior = List;     
      List->next = NULL;

      This = List;
      /* 表头插入法建有五个元素的表 */
      for (i = 1; i <= 5; ++i)
      {
              temp = (LIST *) malloc (sizeof(LIST));
   
              printf ("enter %d Node's date>>",i);
             scanf ("%d", &(temp->element));
          
               temp->prior = This;   
               temp->next = NULL;
              This->next = temp;
             This = temp;
      }

      return (List);
}

/** 插入表 **/
int Insert_List (LIST *List, int i, int element)
{
        LIST *This, *temp;

       This = Get_piout (List, i);

        temp = (LIST*) malloc (sizeof (LIST));

         temp->element = element;
        temp->prior = This;
       temp->next = This->next;
        This->next = temp;

         return 0;
}

/*** 删除元素 ***/
int Delect_List (LIST *List, int i)
{
       LIST *This, *p;

        This = Get_piout (List, i);

         p = This->next;
        p->next->prior = This ;
      This->next = p->next;
        free (p);

        return 0;
}

/**** 找位置函数 ***/
LIST *Get_piout(LIST *List, int i)
{
        LIST *This;
         int j = 0;

         This = List;

        while ((This != NULL)&& (j < i - 1))
         {
               This = This->next;
                ++j;
          }

         if ((This == NULL) || (j > i - 1))
         {
                 return 1;
          }

         return (List);
}

/****打印表***/
void List_List (LIST *List)
{
        LIST *q;

         q = List->next;

         if(q == NULL)
          {
                printf ("empty\n");
                getch();
                 return 1;
         }

         while (q->next != NULL)
         {
               printf ("%d,", q->element);
               q = q->next;
         }
        printf ("%d", q->element);
        getch();
}


char menu (void)
{
       char choice;

        system ("cls");
        printf ("----------------------------------\n");
         printf ("        i insert\n");
        printf ("        d delete\n");
       printf ("        l   list\n");
        printf ("\n\n");
        printf ("        q qiut\n");
        printf ("----------------------------------\n");
         printf ("------Your choice>>");
        scanf ("%c", &choice);

        fflush (stdin);
        return (choice);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值