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

      1 #include <stdio.h>    //增+删+改+查+初始化+输出
      2 #include <stdlib.h>
      3 typedef struct Link {
      4     int  elem;
      5     struct Link *next;
      6 }link;
      7 link * initLink();
      8 //链表插入的函数,p是链表,elem是插入的结点的数据域,add是插入的位置
      9 link * insertElem(link * p, int elem, int add);
     10 //删除结点的函数,p代表操作链表,add代表删除节点的位置
     11 link * delElem(link * p, int add);
     12 //查找结点的函数,elem为目标结点的数据域的值
     13 int selectElem(link * p, int elem);
     14 //更新结点的函数,newElem为新的数据域的值
     15 link *amendElem(link * p, int add, int newElem);
     16 void display(link *p);
     17 int main() {
     18     //初始化链表(1,2,3,4)
     19     printf("初始化链表为:
    ");
     20     link *p = initLink();
     21     display(p);
     22     printf("在第4的位置插入元素5:
    ");
     23     p = insertElem(p, 5, 4);
     24     display(p);
     25     printf("删除第三个位置的元素:
    ");
     26     p = delElem(p, 3);
     27     display(p);
     28     printf("查找元素2的位置:
    ");
     29     int address = selectElem(p, 2);
     30     if (address == -1) {
     31         printf("没有该元素");
     32     }
     33     else {
     34         printf("%d
    ", address);
     35     }
     36     printf("更改第3的位置上的数据为7:
    ");
     37     p = amendElem(p, 3, 7);
     38     display(p);
     39     return 0;
     40 }
     41 link * initLink() {
     42     link * p = (link*)malloc(sizeof(link));//创建一个头结点
     43     link * temp = p;//声明一个指针指向头结点,用于遍历链表
     44     //生成链表
     45     for (int i = 1; i < 5; i++) {
     46         link *a = (link*)malloc(sizeof(link));
     47         a->elem = i;
     48         a->next = NULL;
     49         temp->next = a;
     50         temp = temp->next;
     51     }
     52     return p;
     53 }
     54 link * insertElem(link * p, int elem, int add) {
     55     link * temp = p;//创建临时结点temp
     56     //首先找到要插入位置的上一个结点
     57     for (int i = 1; i < add; i++) {
     58         temp = temp->next;
     59         if (temp == NULL) {
     60             printf("插入位置无效
    ");
     61             return p;
     62         }
     63     }
     64     //创建插入结点c
     65     link * c = (link*)malloc(sizeof(link));
     66     c->elem = elem;
     67     //向链表中插入结点
     68     c->next = temp->next;
     69     temp->next = c;
     70     return  p;
     71 }
     72 link * delElem(link * p, int add) {
     73     link * temp = p;
     74     //遍历到被删除结点的上一个结点
     75     for (int i = 1; i < add; i++) {
     76         temp = temp->next;
     77         if (temp->next == NULL) {
     78             printf("没有该结点
    ");
     79             return p;
     80         }
     81     }
     82     link * del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
     83     temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
     84     free(del);//手动释放该结点,防止内存泄漏
     85     return p;
     86 }
     87 int selectElem(link * p, int elem) {
     88     link * t = p;
     89     int i = 1;
     90     while (t->next) {
     91         t = t->next;
     92         if (t->elem == elem) {
     93             return i;
     94         }
     95         i++;
     96     }
     97     return -1;
     98 }
     99 link *amendElem(link * p, int add, int newElem) {
    100     link * temp = p;
    101     temp = temp->next;//tamp指向首元结点
    102     //temp指向被删除结点
    103     for (int i = 1; i < add; i++) {
    104         temp = temp->next;
    105     }
    106     temp->elem = newElem;
    107     return p;
    108 }
    109 void display(link *p) {
    110     link* temp = p;//将temp指针重新指向头结点
    111     //只要temp指针指向的结点的next不是Null,就执行输出语句。
    112     while (temp->next) {
    113         temp = temp->next;
    114         printf("%d ", temp->elem);
    115     }
    116     printf("
    ");
    117 }

     1.初始化:

     41 link * initLink() {
     42     link * p = (link*)malloc(sizeof(link));//创建一个头结点
     43     link * temp = p;//声明一个指针指向头结点,用于遍历链表
     44     //生成链表
     45     for (int i = 1; i < 5; i++) {
     46         link *a = (link*)malloc(sizeof(link));
     47         a->elem = i;
     48         a->next = NULL;
     49         temp->next = a;
     50         temp = temp->next;
     51     }
     52     return p;
     53 }

    (1)malloc申请头结点,赋给指向该头结点(空间)的指针------- * p (用来代表该链表)

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

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

                  1>为新节点的elem属性赋值

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

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

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

    2.插入:

     54 link * insertElem(link * p, int elem, int add) {
     55     link * temp = p;//创建临时结点temp
     56     //首先找到要插入位置的上一个结点
     57     for (int i = 1; i < add; i++) {
     58         temp = temp->next;
     59         if (temp == NULL) {
     60             printf("插入位置无效
    ");
     61             return p;
     62         }
     63     }
     64     //创建插入结点c
     65     link * c = (link*)malloc(sizeof(link));
     66     c->elem = elem;
     67     //向链表中插入结点
     68     c->next = temp->next;
     69     temp->next = c;
     70     return  p;
     71 }

    (1)创建临时指针 ---------- * temp (用来遍历链表)

    (2)循环寻找插入位置的上一个节点

          1>遍历链表的指针后移一位

          2>判断该指针移动后是否为空,(假设插入位置有效)当循环结束,遍历链表的指针指向了插入位置的上一个节点

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

    (4)为新节点的elem属性赋值

    (5)为新节点的next指向遍历链表的指针的下一个节点(未插入前)   c->next = temp->next;

    (6)将遍历链表的指针指向新节点  temp->next = c;

    3.删除:

     72 link * delElem(link * p, int add) {
     73     link * temp = p;
     74     //遍历到被删除结点的上一个结点
     75     for (int i = 1; i < add; i++) {
     76         temp = temp->next;
     77         if (temp->next == NULL) {
     78             printf("没有该结点
    ");
     79             return p;
     80         }
     81     }
     82     link * del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
     83     temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
     84     free(del);//手动释放该结点,防止内存泄漏
     85     return p;
     86 }

    (1)创建临时指针 ---------- * temp (用来遍历链表)

    (2)循环寻找插入位置的上一个节点

          1>遍历链表的指针后移一位

          2>判断该指针移动后是否为空,(假设插入位置有效)当循环结束,遍历链表的指针指向了插入位置的上一个节点

    (3)声明指针指向被删除节点,防止丢失-------- * del (用来指向被删除节点)      link * del = temp->next;

    (4)将遍历链表的指针指向下下个节点(未插入前)      temp->next = temp->next->next;

    (5)手动释放被删除节点

    4.查找元素n的位置:

     87 int selectElem(link * p, int elem) {
     88     link * t = p;
     89     int i = 1;
     90     while (t->next) {
     91         t = t->next;
     92         if (t->elem == elem) {
     93             return i;
     94         }
     95         i++;
     96     }
     97     return -1;
     98 }

    (1)创建临时指针 ---------- * t(用来遍历链表)

    (2)当用来遍历的指针的next域不为空时

                            1>将指针后移一个节点

           2>判断此时指针指向的节点elem属性是否就是要找的元素n

           3>循环直至找见为止返回1,若未找见返回-1

    5.修改:

     99 link *amendElem(link * p, int add, int newElem) {
    100     link * temp = p;
    101     temp = temp->next;//tamp指向首元结点
    102     //temp指向被删除结点
    103     for (int i = 1; i < add; i++) {
    104         temp = temp->next;
    105     }
    106     temp->elem = newElem;
    107     return p;
    108 }

    升级版:

    1 link *amendElem(link * p, int add, int newElem) {
    2     link * temp = p;
    3     for (int i = 0; i < add; i++) {
    4         temp = temp->next;
    5     }
    6     temp->elem = newElem;
    7     return p;
    8 }

    (1)创建临时指针 ---------- * temp(用来遍历链表)

    (2)循环寻找被删除节点,循环结束temp指向被删除节点

    (3)将temp指向的节点中的elem属性赋值为所传入的值

    6.输出:

    109 void display(link *p) {
    110     link* temp = p;//将temp指针重新指向头结点
    111     //只要temp指针指向的结点的next不是Null,就执行输出语句。
    112     while (temp->next) {
    113         temp = temp->next;
    114         printf("%d ", temp->elem);
    115     }
    116     printf("
    ");
    117 }

    (1)创建临时指针 ---------- * temp(用来遍历链表)

    (2)当temp的next不为空(即存在下一个指针),则temp依次指向下一个节点,输出被指向节点的elem值

  • 相关阅读:
    模拟赛总结
    2018.04.06学习总结
    2018.04.06学习总结
    Java实现 LeetCode 672 灯泡开关 Ⅱ(数学思路问题)
    Java实现 LeetCode 671 二叉树中第二小的节点(遍历树)
    Java实现 LeetCode 671 二叉树中第二小的节点(遍历树)
    Java实现 LeetCode 671 二叉树中第二小的节点(遍历树)
    Java实现 LeetCode 670 最大交换(暴力)
    Java实现 LeetCode 670 最大交换(暴力)
    Java实现 LeetCode 670 最大交换(暴力)
  • 原文地址:https://www.cnblogs.com/wy0526/p/11788478.html
Copyright © 2011-2022 走看看