zoukankan      html  css  js  c++  java
  • 数据结构学习3——双链表

    双链表即双向链表,链表中每个节点有两个指针,分别指向节点的直接前驱和直接后躯。

    特点:从双链表的任一节点开始,都可以非常方便的访问他的前驱节点和后继节点。这也是单链表的缺点,单链表可以方便的访问某一节点的后继节点,但没法访问他的前驱节点。

    双链表的定义及其操作于单链表类似,要注意的就是每个节点的两个指针域。直接上代码

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<malloc.h>
      4 
      5 //定义双链表
      6 typedef struct dnode{
      7     char data;
      8     struct dnode *prior;
      9     struct dnode *next;
     10 }dulinkList;
     11 
     12 //创建双链表:创建链表list 
     13 void dulinkListCreate(dulinkList **list)
     14 {
     15     dulinkList *p,*q;
     16     *list=(dulinkList*)malloc(sizeof(dulinkList));
     17     (*list)->data='\0';
     18     (*list)->prior=NULL;
     19     (*list)->next=NULL;
     20     p=*list;//将头节点地址给p
     21     char ch;
     22     printf("input element:");
     23     while((ch=getchar())!='\n')
     24     {
     25         q=(dulinkList*)malloc(sizeof(dulinkList));
     26         q->data=ch;
     27         q->prior=p;
     28         q->next=NULL;
     29         p->next=q;
     30         p=q;
     31     }
     32 }
     33 
     34 //查找:根据位置查找节点,查找位置为n处的节点并返回
     35 dulinkList * ElemLocatebyNum(dulinkList *list,int n)
     36 {
     37     dulinkList *p;
     38     p=list->next;//第一个节点
     39     int i=1;//从1开始是因为链表头的下一个节点才是链表第一个节点
     40     while(p && i<n)
     41     {
     42         p=p->next;
     43         i++;
     44     }
     45     if(p==NULL || i>n)
     46     {
     47         printf("find error!\n");
     48         return NULL;
     49     }
     50     return p;
     51 }
     52 
     53 //查找:根据数据元素查找,查找数据元素为ch的结点并返回
     54 dulinkList * ElemLocatebyVal(dulinkList *list,char ch)
     55 {
     56     dulinkList *p;
     57     p=list->next;//第一个节点
     58     while(p && p->data!=ch)
     59     {
     60         p=p->next;
     61     }
     62     if(p==NULL)
     63     {
     64         printf("find error!\n");
     65         return NULL;
     66     }
     67     return p;
     68 }
     69 
     70 //插入结点:在链表list位置n处插入元素ch
     71 void dulinkListInsert(dulinkList *list,int n,char ch)
     72 {
     73     dulinkList *p;//链表位置n处的结点
     74     dulinkList *q;//新的结点,内有元素ch
     75     //查找节点p
     76     p=ElemLocatebyNum(list,n);
     77     if(p==NULL)
     78     {
     79         printf("insert error!\n");
     80         return;
     81     }
     82     q=(dulinkList*)malloc(sizeof(dulinkList));
     83     q->data=ch;
     84     q->prior=p->prior;//指出q的直接前驱
     85     p->prior->next=q;//指出q的直接前驱的直接后继
     86     q->next=p;//指出q的直接后继
     87     p->prior=q;//指出p的直接前驱
     88 }
     89 
     90 //删除节点:删除链表list位置n处的节点
     91 void dulinkListDelete(dulinkList *list,int n)
     92 {
     93     dulinkList *p,*q;
     94     p=ElemLocatebyNum(list,n);//查找链表位置为n处的节点p
     95     q=p->prior;
     96     if(p==NULL || q==NULL)
     97     {
     98         printf("delete error!\n");
     99         return;
    100     }
    101     q->next=p->next;
    102     p->next->prior=q;
    103     free(p);
    104 }
    105 
    106 int main()
    107 {
    108     //创建链表
    109     dulinkList *list,*p;
    110     dulinkListCreate(&list);
    111     p=list->next;
    112     if(p==NULL)
    113     {
    114         printf("no element\n");
    115         return 0;
    116     }
    117     printf("list elment:\n");
    118     while(p)
    119     {
    120         printf("%c ",p->data);
    121         p=p->next;
    122     }
    123     printf("\n");
    124     //查找:按位置
    125     p=ElemLocatebyNum(list,5);
    126     printf("position 5 element:%c\n",p->data);
    127     //查找:按数据元素
    128     p=ElemLocatebyVal(list,'f');
    129     printf("f element:%c\n",p->data);
    130     //插入节点
    131     dulinkListInsert(list,6,'Q');
    132     p=list->next;
    133     if(p==NULL)
    134     {
    135         printf("no element\n");
    136         return 0;
    137     }
    138     printf("list elment:\n");
    139     while(p)
    140     {
    141         printf("%c ",p->data);
    142         p=p->next;
    143     }
    144     printf("\n");
    145     //删除节点
    146     dulinkListDelete(list,8);
    147     p=list->next;
    148     if(p==NULL)
    149     {
    150         printf("no element\n");
    151         return 0;
    152     }
    153     printf("list elment:\n");
    154     while(p)
    155     {
    156         printf("%c ",p->data);
    157         p=p->next;
    158     }
    159     printf("\n");
    160     //释放链表的内存空间
    161     p=list;
    162     while(p)
    163     {
    164         list=p;
    165         p=list->next;
    166         free(list);    
    167     }
    168 
    169     return 0;
    170 }

    注意:这段代码严格来说是有问题的,没有在添加和删除节点时没有考虑尾结点的情况,这里为了叙述方便,没有对此进行判断。

    1.创建节点

    2.查找:根据位置和数据元素查找

    3.添加节点:添加时注意逻辑顺序,添加后的节点如下所示,在g和h之间添加Q:

    4.删除节点:最后要记得将删除的节点的内存地址释放掉。删除后的节点如下,删除掉了h和k之间的j:

  • 相关阅读:
    一.创建型模式 Factory
    Tcp/Ip I/O函数
    Tcp/Ip协议理解_简单实例
    Tcp/Ip协议理解_3
    Tcp/Ip协议理解_2
    Tcp/Ip协议理解_1
    abp+angular+bootstrap-table的使用
    Abp mvc angular 添加视图
    Abp添加菜单
    JS 获取一串路径中的文件名称
  • 原文地址:https://www.cnblogs.com/Romi/p/2660052.html
Copyright © 2011-2022 走看看