zoukankan      html  css  js  c++  java
  • 双链表的基本操作-完整代码和拆开分析

      1 #include <stdio.h>      //增+删+改+查+初始化+输出
      2 #include <stdlib.h>
      3 typedef struct line{
      4     struct line * prior;
      5     int data;
      6     struct line * next;
      7 }line;
      8 //双链表的创建
      9 line* initLine(line * head);
     10 //双链表插入元素,add表示插入位置
     11 line * insertLine(line * head,int data,int add);
     12 //双链表删除指定元素
     13 line * delLine(line * head,int data);
     14 //双链表中查找指定元素
     15 int selectElem(line * head,int elem);
     16 //双链表中更改指定位置节点中存储的数据,add表示更改位置
     17 line *amendElem(line * p,int add,int newElem);
     18 //输出双链表的实现函数
     19 void display(line * head);
     20 int main() {
     21     line * head=NULL;
     22     //创建双链表
     23     head=initLine(head);
     24     display(head);
     25     //在表中第 3 的位置插入元素 7
     26     head=insertLine(head, 7, 3);
     27     display(head);
     28     //表中删除元素 2
     29     head=delLine(head, 2);
     30     display(head);
     31 
     32     printf("元素 3 的位置是:%d
    ",selectElem(head,3));
     33     //表中第 3 个节点中的数据改为存储 6
     34     head = amendElem(head,3,6);
     35     display(head);
     36     return 0;
     37 }
     38 line* initLine(line * head){
     39     head=(line*)malloc(sizeof(line));
     40     head->prior=NULL;
     41     head->next=NULL;
     42     head->data=1;
     43     line * list=head;
     44     for (int i=2; i<=5; i++) {
     45         line * body=(line*)malloc(sizeof(line));
     46         body->prior=NULL;
     47         body->next=NULL;
     48         body->data=i;
     49 
     50         list->next=body;
     51         body->prior=list;
     52         list=list->next;
     53     }
     54     return head;
     55 }
     56 line * insertLine(line * head,int data,int add){
     57     //新建数据域为data的结点
     58     line * temp=(line*)malloc(sizeof(line));
     59     temp->data=data;
     60     temp->prior=NULL;
     61     temp->next=NULL;
     62     //插入到链表头,要特殊考虑
     63     if (add==1) {
     64         temp->next=head;
     65         head->prior=temp;
     66         head=temp;
     67     }else{
     68         line * body=head;
     69         //找到要插入位置的前一个结点
     70         for (int i=1; i<add-1; i++) {
     71             body=body->next;
     72         }
     73         //判断条件为真,说明插入位置为链表尾
     74         if (body->next==NULL) {
     75             body->next=temp;
     76             temp->prior=body;
     77         }else{
     78             body->next->prior=temp;
     79             temp->next=body->next;
     80             body->next=temp;
     81             temp->prior=body;
     82         }
     83     }
     84     return head;
     85 }
     86 line * delLine(line * head,int data){
     87     line * temp=head;
     88     //遍历链表
     89     while (temp) {
     90         //判断当前结点中数据域和data是否相等,若相等,摘除该结点
     91         if (temp->data==data) {
     92             temp->prior->next=temp->next;
     93             temp->next->prior=temp->prior;
     94             free(temp);
     95             return head;
     96         }
     97         temp=temp->next;
     98     }
     99     printf("链表中无该数据元素");
    100     return head;
    101 }
    102 //head为原双链表,elem表示被查找元素
    103 int selectElem(line * head,int elem){
    104 //新建一个指针t,初始化为头指针 head
    105     line * t=head;
    106     int i=1;
    107     while (t) {
    108         if (t->data==elem) {
    109             return i;
    110         }
    111         i++;
    112         t=t->next;
    113     }
    114     //程序执行至此处,表示查找失败
    115     return -1;
    116 }
    117 //更新函数,其中,add 表示更改结点在双链表中的位置,newElem 为新数据的值
    118 line *amendElem(line * p,int add,int newElem){
    119     line * temp=p;
    120     //遍历到被删除结点
    121     for (int i=1; i<add; i++) {
    122         temp=temp->next;
    123     }
    124     temp->data=newElem;
    125     return p;
    126 }
    127 //输出链表的功能函数
    128 void display(line * head){
    129     line * temp=head;
    130     while (temp) {
    131         if (temp->next==NULL) {
    132             printf("%d
    ",temp->data);
    133         }else{
    134             printf("%d->",temp->data);
    135         }
    136         temp=temp->next;
    137     }
    138 }

     1.初始化:

     38 line* initLine(line * head){
     39     head=(line*)malloc(sizeof(line));
     40     head->prior=NULL;
     41     head->next=NULL;
     42     head->data=1;
     43     line * list=head;
     44     for (int i=2; i<=5; i++) {
     45         line * body=(line*)malloc(sizeof(line));
     46         body->prior=NULL;
     47         body->next=NULL;
     48         body->data=i;
     49 
     50         list->next=body;
     51         body->prior=list;
     52         list=list->next;
     53     }
     54     return head;
     55 }

    (1)malloc申请第一个结点,赋给指向该结点(空间)的指针------- * head(用来代表该链表)【与单链表不同:不需要头结点

    (2)第一个节点的prior属性赋值为空;

    (3)第一个节点的next属性赋值为空;

    (4)第一个节点的data属性赋值

    (5)声明用来遍历链表的指针------- * list  (用来遍历链表)

    (6)循环创建节点------利用malloc创建 ,赋给指向新申请的节点的指针-------  * body(用来代表新申请的节点)

                  1>为新节点的prior指向为空

        2>为新节点的next指向为空

        3>为新节点的data赋值

        4>第一个结点的next指向新节点  list->next=body;

        5>新节点的prior指向第一个节点  body->prior=list

        6>将遍历链表的指针后移到下一个节点  list=list->next

    2.插入:

    56 line * insertLine(line * head,int data,int add){
     57     //新建数据域为data的结点
     58     line * temp=(line*)malloc(sizeof(line));
     59     temp->data=data;
     60     temp->prior=NULL;
     61     temp->next=NULL;
     62     //插入到链表头,要特殊考虑
     63     if (add==1) {
     64         temp->next=head;
     65         head->prior=temp;
     66         head=temp;
     67     }else{
     68         line * body=head;
     69         //找到要插入位置的前一个结点
     70         for (int i=1; i<add-1; i++) {
     71             body=body->next;
     72         }
     73         //判断条件为真,说明插入位置为链表尾
     74         if (body->next==NULL) {
     75             body->next=temp;
     76             temp->prior=body;
     77         }else{
     78             body->next->prior=temp;
     79             temp->next=body->next;
     80             body->next=temp;
     81             temp->prior=body;
     82         }
     83     }
     84     return head;
     85 }

    (1)malloc申请新结点,赋给指向该结点的指针------- * temp (用来代表新申请的节点)

    (2)第一个节点的prior属性赋值为空;

    (3)第一个节点的next属性赋值为空;

    (4)第一个节点的data属性赋值;

    (5)判断是否插入到第一个位置:

               i f     链表头: 1>新节点的next指向head(此处的head不是代表整个链表,而是代表链表的第一个节点)  temp->next=head;

                  2>head的prior指向新节点         head->prior=temp;

                                   3>将head重新指向第一个节点(已经插入后的)   head=temp;

         else  非链表头:1>声明用来遍历链表的指针------- * body (用来遍历链表)

                 2>循环找插入位置的前一个节点

                 3>  i f         前一个节点的next为空 ----插入链表尾

                             1> 前一个节点的next指向新节点  body->next=temp;

                        2> 新节点的prior指向找见的前一个节点  temp->prior=body;

                 else   -------- 链表中间插入 { 分别称为节点a (前一个节点 body) -> 新节点(新节点 temp) -> 节点b(后一个节点 body->next)}

                        1>节点b的prior指向新节点        body->next->prior=temp;

                        2>新节点的next指向节点b         temp->next=body->next;

                        3>节点a的next指向新节点  body->next=temp;

                        4>新节点的prior指向节点a  temp->prior=body;

    3.删除:

     86 line * delLine(line * head,int data){
     87     line * temp=head;
     88     //遍历链表
     89     while (temp) {
     90         //判断当前结点中数据域和data是否相等,若相等,摘除该结点
     91         if (temp->data==data) {
     92             temp->prior->next=temp->next;
     93             temp->next->prior=temp->prior;
     94             free(temp);
     95             return head;
     96         }
     97         temp=temp->next;
     98     }
     99     printf("链表中无该数据元素");
    100     return head;
    101 }

    (1)声明用来遍历链表的指针 -------- * temp (用来遍历链表) 

    (2)当指针不为0时

          i f   当前指针所指节点data属性等于要找的data { 分别称为节点a(temp->prior)    节点b(要删除的节点 temp)   节点c(temp->next)}

              1> 节点a的next指向节点c  temp->prior->next=temp->next;

              2>节点c的prior指向节点a  temp->next->prior=temp->prior;

              3>释放节点b

         else  指针继续移向下一个节点 直到找见要找的data

    4.查找元素n的位置:

    102 //head为原双链表,elem表示被查找元素
    103 int selectElem(line * head,int elem){
    104 //新建一个指针t,初始化为头指针 head
    105     line * t=head;
    106     int i=1;
    107     while (t) {
    108         if (t->data==elem) {
    109             return i;
    110         }
    111         i++;
    112         t=t->next;
    113     }
    114     //程序执行至此处,表示查找失败
    115     return -1;
    116 }

    (1)声明用来遍历链表的指针 -------- * t(用来遍历链表) 

    (2)循环查找:如果找见了就返回位置(这里用 i 来记录);找不见就  i++  指针下移   一直循环,直到找见为止

    5.修改:

    //更新函数,其中,add 表示更改结点在双链表中的位置,newElem 为新数据的值
    118 line *amendElem(line * p,int add,int newElem){
    119     line * temp=p;
    120     //遍历到被删除结点
    121     for (int i=1; i<add; i++) {
    122         temp=temp->next;
    123     }
    124     temp->data=newElem;
    125     return p;
    126 }

    (1)声明用来遍历链表的指针 -------- * temp(用来遍历链表) 

    (2)循环找到被删除节点(前几篇随笔有详细介绍~欢迎看唠~)

    (3)修改数据域

    6.输出:

    127 //输出链表的功能函数
    128 void display(line * head){
    129     line * temp=head;
    130     while (temp) {
    131         if (temp->next==NULL) {
    132             printf("%d
    ",temp->data);
    133         }else{
    134             printf("%d->",temp->data);
    135         }
    136         temp=temp->next;
    137     }
    138 }

    (1)声明用来遍历链表的指针 -------- * temp(用来遍历链表) 

    (2)当节点不为零时,分尾节点和普通节点两种。循环输出普通节点 -> 输出尾节点 -> 跳出循环,程序结束

  • 相关阅读:
    隐藏 MOSS 2007 页面版本工具栏
    用于显示原始XML形式的搜索结果的XSLT
    MOSS 2007 日志设置
    在布局页面“文章页面中”添加,自定义UserControl
    MOSS 2007 最简单的自定义搜索框 SearchBox
    Asp.net常用状态管理方案分析
    提高asp.net的性能的几种方法(转)
    VS2005下如何用预编译命令来发布站点
    asp.net控件设计时支持(1)
    解决Enterprise Library January 2006不能加密配置文件的方法(转)
  • 原文地址:https://www.cnblogs.com/wy0526/p/11788493.html
Copyright © 2011-2022 走看看