zoukankan      html  css  js  c++  java
  • C语言版本:单链表的实现

    slist.h

     1 #ifndef __SLIST_H__
     2 #define __SLIST_H__
     3 
     4 #include<cstdio>
     5 #include<malloc.h>
     6 #include<assert.h>
     7 typedef int ElemType;
     8 typedef struct Node { //定义单链表中的结点信息
     9     ElemType data; //结点的数据域
    10     struct Node *next; //结点的指针域
    11 }Node,*PNode;
    12 typedef struct List { //定义单链表的链表信息
    13     PNode first; //first指向单链表中的第一个结点
    14     PNode last; //last指向单链表中的最后一个结点
    15     size_t size; //记录单链表中的结点个数
    16 }List;
    17 
    18 void InitList(List *list);//初始化单链表
    19 void push_back(List *list, ElemType x);//在单链表的末尾插入元素
    20 void push_front(List *list, ElemType x);//在单链表的头部插入元素
    21 void show_list(List *list);//打印单链表
    22 void pop_back(List *list);//删除单链表的最后一个元素
    23 void pop_front(List *list);//删除单链表的第一个元素
    24 void insert_val(List *list, ElemType val);//将数据元素插入到单链表中(要求此时单链表中的数据元素顺序排列)
    25 Node* find(List *list, ElemType x);//查找单链表中数据值为x的结点
    26 int length(List *list);//求单链表的长度
    27 void delete_val(List *list, ElemType x);//按值删除单链表中的某个数据元素
    28 void sort(List *list);//对单链表进行排序
    29 void reverse(List *list);//逆置单链表
    30 void clear(List *list);//清除单链表
    31 void destroy(List *list);//摧毁单链表
    32 
    33 #endif //__SLIST_H__

    slist.cpp

      1 #include"slist.h"
      2 
      3 void InitList(List *list) {
      4     list->first = list->last = (Node*)malloc(sizeof(Node)); //头结点
      5     assert(list->first != NULL);
      6     list->first->next = NULL;
      7     list->size = 0;
      8 }
      9 
     10 void push_back(List *list, ElemType x) {
     11     //step 1:创建一个新的结点
     12     Node *s = (Node*)malloc(sizeof(Node));
     13     assert(s != NULL);
     14     s->data = x;
     15     s->next = NULL;
     16     //step 2:将新结点插入单链表的表尾
     17     list->last->next = s;
     18     list->last = s;
     19     //step 3:更新单链表的长度
     20     list->size++;
     21 }
     22 
     23 void push_front(List *list, ElemType x) {
     24     //step 1:创建一个新的结点
     25     Node *s = (Node*)malloc(sizeof(Node));
     26     assert(s != NULL);
     27     s->data = x;
     28     s->next = NULL;
     29     //step 2:将新结点插入单链表的表头
     30     s->next = list->first->next;
     31     list->first->next = s;
     32     //step 3:判断插入的结点是否是单链表的第一个结点,若是更新链表的尾指针
     33     if (list->size == 0)
     34         list->last = s;
     35     //step 4:更新单链表的长度
     36     list->size++;
     37 }
     38 
     39 void show_list(List *list) {
     40     //step 1:指针p指向单链表的第一个结点
     41     Node *p = list->first->next;
     42     //step 2:循环打印结点的信息
     43     while (p != NULL) {
     44         printf("%d->", p->data);
     45         p = p->next;
     46     }
     47     printf("Nul.
    ");
     48 
     49 }
     50 
     51 void pop_back(List *list) {
     52     //step 1:判断单链表是否为空
     53     if (list->size == 0) return;
     54     //step 2:定义指针p使其指向目标结点的前一个结点
     55     Node *p = list->first;//从头结点开始
     56     while (p->next != list->last)
     57         p = p->next;
     58     //step 3:删除目标结点
     59     free(list->last);
     60     list->last = p;
     61     list->last->next = NULL;
     62     //step 4:更新单链表的长度
     63     list->size--;
     64 }
     65 
     66 void pop_front(List *list) {
     67     //step 1:判断单链表是否为空
     68     if (list->size == 0) return;
     69     //step 2:定义指针p使其指向目标结点的前一个结点
     70     Node *p = list->first->next;
     71     //step 3:删除目标结点
     72     list->first->next = p->next;
     73     free(p);
     74     //step 4:判断删除的结点是否是单链表的最后一个结点,若是则更新单链表的尾指针
     75     if (list->size == 1)
     76         list->last = list->first;
     77     //step 4:更新单链表的长度
     78     list->size--;
     79 }
     80 
     81 void insert_val(List *list, ElemType x) {
     82     //step 1:创建一个新的结点
     83     Node *s = (Node*)malloc(sizeof(Node));
     84     assert(s != NULL);
     85     s->data = x;
     86     s->next = NULL;
     87     //step 2:定义指针p使其指向待插入位置的前一个结点
     88     Node *p = list->first;//从头结点开始
     89     while (p->next != NULL && p->next->data < s->data)
     90         p = p->next;
     91     //step 3:判断结点的待插入位置是否是表尾,若是则更新单链表的尾指针
     92     if (p->next == NULL)
     93         list->last = s;
     94     //step 4:插入结点
     95     s->next = p->next;
     96     p->next = s;
     97     //step 5:更新单链表长度
     98     list->size++;
     99 }
    100 
    101 Node* find(List *list, ElemType x) {
    102     //step 1:指针p指向单链表的第一个结点
    103     Node *p = list->first->next;
    104     //step 2:按照循环顺序查找链表结点
    105     while (p != NULL && p->data != x)
    106         p = p->next;
    107     return p;
    108 }
    109 
    110 int length(List *list) {
    111     return list->size;
    112 }
    113 
    114 void delete_val(List *list, ElemType x) {
    115     //step 1:判断单链表是否为空
    116     if (list->size == 0) return;
    117     //step 2:确定结点在单链表中的位置,并判断其是否存在于单链表中
    118     Node *p = find(list, x);
    119     if (p == NULL) {
    120         printf("要删除的数据不存在!
    ");
    121         return;
    122     }
    123     //step 3:判断结点位置是否是表尾
    124     if (p == list->last)//是表尾
    125         pop_back(list);
    126     else {//不是表尾
    127         Node *q = p->next;
    128         p->data = q->data;
    129         p->next = q->next;
    130         free(q);
    131         list->size--;
    132     }
    133 }
    134 
    135 void sort(List *list) {
    136     //step 1:判断单链表中的结点数是否为0或1
    137     if (list->size == 0 || list->size == 1) return;
    138     //step 2:将单链表中第一个结点之后的链表部分截出,方便重新按顺序插入链表之中
    139     Node *s = list->first->next; // 指针s指向单链表的第一个节点
    140     Node *p = s->next;//q指向s后面的结点
    141     list->last = s;//单链表的尾指针指向单链表的第一个结点
    142     list->last->next = NULL;//截断链表
    143     //step 3:将截出的链表中的结点根据其数据域大小重新插入到原来链表中
    144     while (p != NULL) {
    145         s = p;
    146         p = p->next;
    147         Node *q = list->first;
    148         while (q->next != NULL && q->next->data < s->data)
    149             q = q->next;
    150         if (q->next == NULL)//判断q此时指向的是否是单链表的最后一个结点,若是则更新链表的尾指针
    151             list->last = s;
    152         //将结点重新插入链表
    153         s->next = q->next;
    154         q->next = s;
    155     }
    156 }
    157 
    158 void reverse(List *list) {
    159     //step 1:判断单链表中的结点数是否为0或1
    160     if (list->size == 0 || list->size == 1) return;
    161     //step 2:将单链表中第一个结点之后的链表部分截出,然后将截出的链表中的结点按头插法重新插入到原链表中
    162     Node *p = list->first->next;
    163     Node *q = p->next;
    164     list->last = p;
    165     list->last->next = NULL;
    166 
    167     while (q != NULL) {
    168         p = q;
    169         q = q->next;
    170         p->next = list->first->next;
    171         list->first->next = p;
    172     }
    173 }
    174 
    175 void clear(List *list) {
    176     //step 1:判断单链表是否为空
    177     if (list->size == 0) return;
    178     //step 2:释放单链表中的每一个结点
    179     Node *p = list->first->next;
    180     while (p != NULL) {
    181         list->first->next = p->next;
    182         free(p);
    183         p = list->first->next;
    184     }
    185     //step 3:头指针和尾指针重新都指向头结点
    186     list->last = list->first;
    187     //step 4:更新链表长度
    188     list->size = 0;
    189 }
    190 
    191 void destroy(List *list) {
    192     //step 1:清空单链表
    193     clear(list);
    194     //step 2:释放头结点
    195     free(list->first);
    196     //step 3:头指针和尾指针都赋值为空
    197     list->first = list->last = NULL;
    198 }

    main.cpp

     1 #include"slist.h"
     2 
     3 void main() {
     4     List mylist;
     5     InitList(&mylist);
     6 
     7     ElemType item;
     8     Node *p = NULL;
     9     int select = 1;
    10     while (select) {
    11         printf("*******************************************
    ");
    12         printf("*[1]  push_back        [2]  push_front    *
    ");
    13         printf("*[3]  show_list        [4]  pop_back      *
    ");
    14         printf("*[5]  pop_front        [6]  insert_val    *
    ");
    15         printf("*[7]  find             [8]  length        *
    ");
    16         printf("*[9]  delete_val       [10] sort          *
    ");
    17         printf("*[11] reverse          [12] clear         *
    ");
    18         printf("*[13*] destroy         [0] quit_system    *
    ");
    19         printf("*******************************************
    ");
    20         printf("请选择:>>");
    21         scanf("%d", &select);
    22         if (select == 0) break;
    23         switch (select) {
    24         case 1:
    25             printf("请输入要插入的数据(-1结束):>");
    26             while (scanf("%d", &item), item != -1) {
    27                 push_back(&mylist, item);
    28             }
    29             break;
    30         case 2:
    31             printf("请输入要插入的数据(-1结束):>");
    32             while (scanf("%d", &item), item != -1) {
    33                 push_front(&mylist, item);
    34             }
    35             break;
    36         case 3:
    37             show_list(&mylist);
    38             break;
    39         case 4:
    40             pop_back(&mylist);
    41             break;
    42         case 5:
    43             pop_front(&mylist);
    44             break;
    45         case 6:
    46             printf("请输入要插入的数据:>");
    47             scanf("%d", &item);
    48             insert_val(&mylist, item);
    49             break;
    50         case 7:
    51             printf("请输入要查找的数据:>");
    52             scanf("%d", &item);
    53             p = find(&mylist, item);
    54             if (p == NULL)
    55                 printf("要查找的数据在单链表中不存在!
    ");
    56             break;
    57         case 8:
    58             printf("单链表的长度为%d
    ", length(&mylist));
    59             break;
    60         case 9:
    61             printf("请输入要删除的值:>");
    62             scanf("%d", &item);
    63             delete_val(&mylist, item);
    64             break;
    65         case 10:
    66             sort(&mylist);
    67             break;
    68         case 11:
    69             reverse(&mylist);
    70             break;
    71         case 12:
    72             clear(&mylist);
    73             break;
    74             //case 13:
    75             //destroy(&mylist);
    76             //break;
    77         default:
    78             printf("选择错误,请重新选择!
    ");
    79             break;
    80         }
    81     }
    82     destroy(&mylist); //程序结束,摧毁链表
    83 }
  • 相关阅读:
    [转载]iOS 开发中为什么更新UI都要放在主线程中?
    GCD小结
    多线程的实现
    图片缓存、PathForResource、NSBundle
    IOS全路径和文件名方法、NSBundle
    plist文件
    iphone区别翻新机
    iPhone4S国行、港版、美版、妖机识别与选购(转)
    应用沙盒
    IOS实现新特性功能
  • 原文地址:https://www.cnblogs.com/duwenxing/p/7569376.html
Copyright © 2011-2022 走看看