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

    未优化版本:http://www.cnblogs.com/duwenxing/p/7569376.html

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

    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 }
  • 相关阅读:
    RatProxy
    Jacob
    系统二级运维之业务单据错误处理
    材料的构成 —— 塑料
    作文 —— 诙谐、幽默、调侃、批判
    作文 —— 诙谐、幽默、调侃、批判
    (中英)作文 —— 标题与小标题
    公司的组成
    公司的组成
    数据结构的时间复杂度与空间复杂度、及相关证明
  • 原文地址:https://www.cnblogs.com/duwenxing/p/7569591.html
Copyright © 2011-2022 走看看