zoukankan      html  css  js  c++  java
  • 单链表(不带头结点)

     初稿:2017-11-18 23:50:40

    单链表的结点:数据域,指针域(存储下一结点的地址)

    包含函数:初始化,销毁,清空,尾插法和头插法批量录入数据,统计结点的个数,追加结点,删除结点,正序和逆序打印链表。

    知识点:

    (1)一个结构体内部不能含有结构体本身类型的结点,但可以含有本类型的指针。

    (2)易错点:删除,插入的操作可能会影响首结点的地址,要单独处理,不注意代码运行会全是bug!

    (3)逆序打印采用的递归,可着重看一下。

    (4)批量录入数据有两种方法:头插法,链表的顺序和输入顺序正好相反。尾插法则正好相同。

    (5)删除结点采用O(1)方法,分4种情况

    • 首结点&&最后一个结点:*L = null
    • 首结点&&不是最后一个结点:先保存下一结点的地址,用下一结点覆盖本应删除的目的结点,删除事先保存的结点
    • 不是首结点&&最后一个结点:无法删除,必须采用伴随扫描指针的方式,获知前驱指针,才能删除
    • 不是首结点&&不是最后一个结点:采用情况2的方法

    (6)伴随指针查找value的代码(两个紧邻指针一起扫描单链表,一般删除结点时使用)

    //至少含有一个元素,即不为空
    
    p = frist; q = NULL;
    
    while (p != NULL && p->data != value)
    
    {
    
        //在此通过p可以操作所有的元素
    
        q = p;/*这两个语句是不可分割的,是一个整体,相当于原语*/
    
        p = p->next;/*在这个整体前后,q一定指向p的前驱*/
    
        //在此p:2 to last;q:1 to last - 1
    
    }
    
    /*出循环后,q仍旧指向p的前驱,只要p不指向空*/
    
    /*适用于查找value,并进行牵扯到其前驱的操作*/
    
    注意第一个结点就是value的情况!,出循环后前驱指针是null
      1 #include"头文件.h"
      2 /*头插法,逆序
      3 尾插法,正序*/
      4 typedef struct node {
      5     int data;
      6     struct node *next;
      7 }Node,*LinkList;
      8 /*初始化单链表*/
      9 void InitList(LinkList *L) {
     10     *L = null;
     11 }
     12 /*销毁单链表*/
     13 void DestroyList(LinkList *L) {
     14     if (*L == null)
     15         return;
     16     LinkList p;
     17     while (*L != null) {
     18         p = (*L)->next;//临时保存下一结点的地址
     19         free(*L);
     20         *L = p;
     21     }
     22 }
     23 /*清空单链表*/
     24 void ClearList(LinkList *L) {
     25     DestroyList(L);
     26 }
     27 /*批量录入数据:头插法*/
     28 void HeadCreate(LinkList *L) {
     29     int elem; Node *p;
     30     while (scanf_s("%d", &elem), elem != -1) {
     31         if (*L == null) {
     32             *L = (LinkList)malloc(sizeof(Node));
     33             if (*L == null) exit(-1);
     34             (*L)->data = elem;
     35             (*L)->next = null;
     36         }
     37         else {
     38             p = (LinkList)malloc(sizeof(Node));
     39             if (!p) exit(-1);
     40             p->data = elem;
     41             p->next = (*L)->next;
     42             (*L)->next = p;
     43         }
     44     }
     45 }
     46 /*批量录入数据:尾插法*/
     47 void TailCreate(LinkList *L) {
     48     int elem; Node *tail = null,*p;
     49     while (scanf_s("%d", &elem), elem != -1) {
     50         if (*L == null) {
     51             *L = (LinkList)malloc(sizeof(Node));
     52             if (*L == null) exit(-1);
     53             (*L)->data = elem;
     54             (*L)->next = null;
     55             tail = *L;
     56         }
     57         else {
     58             p = (LinkList)malloc(sizeof(Node));
     59             if (!p) exit(-1);
     60             p->data = elem;
     61             p->next = null;
     62             tail->next = p;
     63             tail = p;
     64         }
     65     }
     66 }
     67 /*统计结点的个数*/
     68 int TotalNum(LinkList *L) {
     69     int count = 0;//计数器
     70     LinkList p = *L;
     71     for (; p; p = p->next)
     72         ++count;
     73     return count;
     74 }
     75 /*在表尾追加元素value*/
     76 void AddToTail(LinkList *L,int value) {
     77     Node *p = null,*q = null;
     78     if (*L == null) {
     79         *L = (LinkList)malloc(sizeof(Node));
     80         if (*L == null) exit(-1);
     81         (*L)->data = value;
     82         (*L)->next = null;
     83     }
     84     else {
     85         for (p = *L; p->next != null; p = p->next)
     86             ;
     87         q = (LinkList)malloc(sizeof(Node));
     88         if (!q) exit(-1);
     89         q->data = value;
     90         q->next = p->next;
     91         p->next = q;
     92     }
     93 }
     94 /*删除第一个值是value结点*/
     95 void Remove(LinkList *L,int value) {
     96     if (*L == null)
     97         return;
     98     Node *p = *L,*q;
     99     while (p && p->data != value) {
    100         p = p->next;
    101     }
    102     if (!p) {
    103         printf("没有该元素!
    "); return;
    104     }
    105     if (p == *L) {
    106         if (p->next == null) {
    107             *L = null;
    108             free(p);
    109         }
    110         else {
    111             p = (*L)->next;
    112             (*L)->data = (*L)->next->data;
    113             (*L)->next = (*L)->next->next;
    114             free(p);
    115         }
    116     }
    117     else {
    118         if (p->next != null) {
    119             p->data = p->next->data;
    120             q = p->next;
    121             p->next = q->next;
    122             free(q);
    123         }
    124         else {
    125             printf("无法删除,请采用伴随扫描指针的方法删除。
    ");
    126             return;
    127         }
    128     }
    129 
    130 }
    131 /*打印单链表*/
    132 void Print(LinkList *L) {
    133     if (*L == null)
    134         return;
    135     Node *p = *L;
    136     for (; p; p = p->next) {
    137         printf("%d ", p->data);
    138     }
    139     printf("
    ");
    140 }
    141 /*递归逆序打印单链表*/
    142 void FromTailPrint(LinkList *L) {
    143     if (*L == null)
    144         return;
    145     FromTailPrint(&(*L)->next);
    146     printf("%d ", (*L)->data);
    147 }
    148 int main() {
    149     LinkList L;
    150     InitList(&L);
    151     TailCreate(&L);
    152     fflush(stdin);
    153     printf("打印单链表
    ");
    154     Print(&L);
    155     printf("单链表结点的个数是:%d
    ", TotalNum(&L));
    156     printf("删除9
    ");
    157     Remove(&L, 9);
    158     printf("打印单链表
    ");
    159     Print(&L);
    160     printf("追加10
    ");
    161     AddToTail(&L, 10);
    162     printf("逆序打印单链表
    ");
    163     FromTailPrint(&L);
    164     system("pause");
    165     return 0;
    166 }

    运行结果:

  • 相关阅读:
    到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf
    陀螺仪、加速计和磁力计
    UIImage加载图片的方式以及Images.xcassets对于加载方法的影响
    Java-Jdbc
    3.1 基本数据类型
    第三章 数据类型和变量
    2.2.4 给java应用打包
    2.2.3 运行java程序
    2.2.2 编译java源文件
    2.2.1 jdk简介
  • 原文地址:https://www.cnblogs.com/joyeehe/p/7858451.html
Copyright © 2011-2022 走看看