zoukankan      html  css  js  c++  java
  • 数据结构笔记#单链表

    开始学习数据结构这个大坑了啊。。。赶紧记一记各种数据结构的写法。

    我的数据结构代码

    以下是单链表的C语言实现,只有一些最基本的功能。

    我这个链表有一个表头(头节点),储存了该链表的长度。但是这个不是必须的,数据结构没有一个确定的答案,只要合适自己就行。

    头节点储存链表的长度,指针指向第一个节点。

     

    LinkedList.h

     该文件定义了链表,并声明了一些操作链表的函数

     1 #ifndef _LINKEDLIST_H_
     2 #define _LINKEDLIST_H_
     3 
     4 #include<stdlib.h>
     5 #include<stdio.h>
     6 
     7 typedef int DataType;
     8 
     9 struct node
    10 {
    11     DataType data;
    12     struct node *next;
    13 };
    14 typedef struct node NODE;
    15 typedef NODE *HEAD;
    16 
    17 //初始化链表,创建一个头节点,值为该链表长度
    18 void InitList(NODE **L);
    19 
    20 //头插法创建整表
    21 void CreateListHead(NODE **L);
    22 
    23 //尾插法创建整表
    24 void CreateListTail(NODE **L);
    25 
    26 //销毁链表
    27 void DestroyList(NODE **L);
    28 //销毁节点及以后的节点
    29 void DestroyNode(NODE *N);
    30 
    31 //获取位置i的数据
    32 void GetElem(NODE L,DataType i, DataType *num);
    33 
    34 //获取数据num的位置
    35 int LocateElem(NODE L, DataType num);
    36 
    37 //获取数据cur之前的一个数据
    38 int PriorElem(NODE L, DataType cur_e, DataType *pre_e);
    39 
    40 //获取数据cur之后的一个数据
    41 int NextElem(NODE L, DataType cur_e, DataType *next_e);
    42 
    43 //在位置i插入元素num
    44 void ListInsert(NODE *L, DataType i, DataType num);
    45 
    46 //在位置i删除元素,并将其值给num
    47 void ListDelete(NODE *L, DataType i, DataType *num);
    48 
    49 //打印整表
    50 void ListTraverse(NODE L);
    51 
    52 #endif

    LinkedList.c

    在该文件中我们具体的定义每个函数的功能。

    首先我们将头文件包含进来

    #include"LinkedList.h"
    然后从上往下依次定义函数。
    第一个是初始化链表的函数,作用是新建一个头节点,并将传入的指针指向该头节点。
    1 void InitList(NODE **L)
    2 {
    3     *L = (NODE*)malloc(sizeof(NODE));
    4     (*L)->data = 0;
    5     (*L)->next = NULL;
    6 }

    注意该函数的形参有两个**,需要传入的实参为指向指针的指针。

    比如我们在main函数中,

    HEAD head;

    这个head是指向NODE的指针(因为我在头文件中typedef NODE *HEAD),那么传入它的时候就要写成

    InitList(&head);

    函数接收的值即指向该指针的指针。

    为什么这么做呢?

    因为我们要创建链表,而一开始head指针是空的,我们需要修改它的值让他指向新创建的头节点。

    我们都知道要修改某个数据的值,只能向函数传入指向该数据的指针;而我们要修改这个head指针的值,那就要传入指向他的指针。

    对于这个链表来说,如果我们想修改头指针的值(通常发生在创建链表和销毁链表的时候),那么相应的函数就要接受指向头指针的指针。

    比如下面的头插法和尾插法创建链表,以及链表的销毁。

     头插法创建链表

    特性是输入的数据与最后生成的链表顺序相反

     1 void CreateListHead(NODE **L)
     2 {
     3     InitList(L);
     4     int num;
     5     NODE *temp;
     6     while (scanf("%d", &num) && num != 999)
     7     {
     8         temp = (NODE*)malloc(sizeof(NODE));
     9         temp->data = num;
    10         //新建的节点指向头节点后的一个节点
    11         temp->next = (*L)->next;
    12         //头节点指向新建的节点,插队成功
    13         (*L)->next = temp;
    14         (*L)->data++;
    15     }
    16 }

    尾插法创建链表

    特性与头插法相反,输入的数据与生成的链表顺序相同,但代价是使用的时候需要多维护一个不断指向尾部的指针。

     1 void CreateListTail(NODE **L)
     2 {
     3     InitList(L);
     4     int num;
     5     NODE *temp;
     6     //指向尾部
     7     NODE *tail_pointer;
     8     //刚开始头节点为链表的尾部
     9     tail_pointer = *L;
    10     while (scanf("%d", &num) && num != 999)
    11     {
    12         temp = (NODE*)malloc(sizeof(NODE));
    13         //尾部的下一个指向新建的节点
    14         tail_pointer->next = temp;
    15         temp->data = num;
    16         temp->next = NULL;
    17 
    18         //新建的节点变成尾部
    19         tail_pointer = temp;
    20         (*L)->data++;
    21     }
    22 }

    链表的销毁

    注意只需在main函数中调用DestroyList即可,DestroyNode函数不需要人为调用。

     1 void DestroyNode(NODE *N)
     2 {
     3     NODE *temp = NULL;
     4     if (N != NULL)
     5     {
     6         temp = N;
     7         N = N->next;
     8         free(temp);
     9         temp = NULL;
    10 
    11         DestroyNode(N);
    12     }
    13 }
    14 
    15 void DestroyList(NODE **L)
    16 {
    17     DestroyNode(*L);
    18     *L = NULL;
    19 }

    使用了递归?(又是你?) 

    说实话我不知道这个DeleteList能不能正常工作,dubug半天也看不出过了这个函数之后到底起没起作用。。。。但是按照代码分析似乎好像也许是可以工作的。

    按照递归从头开始删除每一个节点。递归真是个神奇的东西。

    剩下的函数定义都直接贴出来了,都是比较简单的东西,对照头文件看看就可以了。

      1 void GetElem(NODE L, DataType i, DataType *num)
      2 {
      3     HEAD temp;
      4     int lop;
      5 
      6     temp = &L;
      7     temp = temp->next;
      8     for (lop = 0; lop < i; lop++)
      9     {
     10         temp = temp->next;
     11     }
     12 
     13     *num = temp->data;
     14     temp = NULL;
     15 }
     16 
     17 int LocateElem(NODE L, DataType num)
     18 {
     19     HEAD temp;
     20     int lop;
     21 
     22     temp = &L; 
    24
    temp = temp->next; 25 26 for (lop = 0; lop < L.data; lop++) 27 { 28 if (num == temp->data) 29 { 30 return lop + 1; 31 } 32 else 33 { 34 temp = temp->next; 35 } 36 } 37 38 return 0; 39 } 40 41 int PriorElem(NODE L, DataType cur_e, DataType * pre_e) 42 { 43 int lop; 44 NODE *target,*cursor; 45 target = &L; 46 cursor = &L; 47 cursor = cursor->next; 48 for (lop = 0; lop < L.data ; lop++) 49 { 50 if (cursor->data == cur_e) 51 { 52 if (lop == 0) 53 { 54 return 0; 55 } 56 *pre_e = target->data; 57 return 1; 58 } 59 else 60 { 61 cursor = cursor->next; 62 target = target->next; 63 } 64 } 65 return -1; 66 } 67 68 int NextElem(NODE L, DataType cur_e, DataType * next_e) 69 { 70 int lop; 71 NODE *cursor; 72 cursor = &L; 73 cursor = cursor->next; 74 75 for (lop = 0; lop < L.data ; lop++) 76 { 77 if (cursor->data == cur_e) 78 { 79 if (lop == L.data - 1) 80 { 81 return 0; 82 } 83 *next_e = cursor->next->data; 84 return 1; 85 } 86 cursor = cursor->next; 87 } 88 return -1; 89 } 90 91 void ListInsert(NODE *L, DataType i, DataType num) 92 { 93 HEAD temp; 94 NODE *temp_node; 95 int lop; 96 97 temp = L; 98 99 for (lop = 0; lop < i; lop++) 100 { 101 temp = temp->next; 102 } 103 temp_node = (NODE*)malloc(sizeof(NODE)); 104 temp_node->data = num; 105 temp_node->next = NULL; 106 107 if (lop != L->data) 108 { 109 temp_node->next = temp->next; 110 } 111 else 112 { 113 temp_node->next = NULL; 114 } 115 temp->next = temp_node; 116 117 temp = L; 118 temp->data++; 119 temp = NULL; 120 temp_node = NULL; 121 } 122 123 void ListDelete(NODE *L, DataType i, DataType *num) 124 { 125 HEAD temp; 126 NODE *temp_delete; 127 int lop; 128 129 temp = L; 130 131 for (lop = 0; lop < i; lop++) 132 { 133 temp = temp->next; 134 } 135 temp_delete = temp->next; 136 *num = temp_delete->data; 137 temp->next = temp->next->next; 138 139 free(temp_delete); 140 141 temp = L; 142 temp->data--; 143 temp = NULL; 144 temp_delete = NULL; 145 } 146 147 void ListTraverse(NODE L) 148 { 149 HEAD temp; 150 temp = &L; 151 int timer= 0; 152 printf("The Length Of This List Is: %d ", temp->data); 153 printf("The Member(s) Are: "); 154 while (temp->next!= NULL) 155 { 156 temp = temp->next; 157 printf("%d) %d ", timer++, temp->data); 158 } 159 printf(" ============================ "); 160 }

    最后可以写一个main函数测试一下该链表。所有的函数都可以试试。我只调用了几个函数。

     1 #include"LinkedList.h"
     2 
     3 int main()
     4 {
     5     HEAD  head = NULL;
     6     int a = -1;
     7 
     8     //输入999终止创建,以下方法任选一个
     9 
    10     //CreateListHead(&head);
    11     CreateListTail(&head);
    12 
    13     ListTraverse(*head);
    14 
    15     if (PriorElem(*head, 1, &a) == 1)
    16     {
    17         printf("前驱元素 %d
    ", a);
    18     }
    19 
    20     if (NextElem(*head, 4, &a) == 1)
    21     {
    22         printf("后继元素 %d
    ", a);
    23     }
    24     DestroyList(&head);
    25     return 0;
    26 }

    前驱后继元素那里的值可以自己更换,我用的是1和4

  • 相关阅读:
    java接口返回json数据格式
    ajax请求报406问题
    ajax跨域问题
    js、css等引入文件路径正确,却报404的解决办法
    HttpServletResponse,HttpServletRequest详解
    python学习(十六)os使用
    python学习(十五)python读取配置yaml
    python学习(十四)python操作发送邮件(163邮箱)
    python学习(十三)python使用pymsql链接数据库操作
    python学习(十二)python正则表达式
  • 原文地址:https://www.cnblogs.com/makejeffer/p/4790728.html
Copyright © 2011-2022 走看看