zoukankan      html  css  js  c++  java
  • [数据结构与算法] : 单向链表

    头文件

     1 // filename: list.h
     2 typedef int ElementType;
     3 
     4 #ifndef _LIST_H_
     5 #define _LIST_H_
     6 
     7 struct Node;
     8 typedef struct Node *PtrToNode;
     9 typedef PtrToNode List;
    10 typedef PtrToNode Position;
    11 
    12 List MakeEmpty(List L);
    13 int IsEmpty(List L);
    14 int IsLast(Position P, List L);
    15 Position Find(ElementType X, List L);
    16 void Delete(ElementType X, List L);
    17 Position FindPrevious(ElementType X, List L);
    18 void Insert(ElementType X, List L, Position P);
    19 void DeleteList(List L);
    20 Position Header(List L);
    21 Position First(List L);
    22 Position Advance(Position P);
    23 ElementType Retrieve(Position P);
    24 void PrintElement(ElementType X);
    25 void TraversList(List L);        // 正序遍历(递归法)
    26 void ReverseTraversList(List L); // 逆序遍历(递归法)
    27 void TraverseL(List L);          // 对于一个庞大的栈递归可能造成越出栈空间, 使用goto消除尾递归
    28 void TraverseL2(List L);         // while循环遍历
    29 
    30 #endif

    源文件

    filename: list.c

      1 #include "list.h"
      2 #include <malloc.h>
      3 #include <stdlib.h>
      4 
      5 struct Node
      6 {
      7     ElementType Element;
      8     PtrToNode Next;
      9 };
     10 
     11 // 创建或者清空链表
     12 List MakeEmpty(List L)
     13 {
     14     if(L != NULL)
     15         DeleteList(L);
     16     else
     17     {
     18         L = (List)malloc( sizeof(struct Node) );
     19         if(L == NULL)
     20         {
     21             exit(-1);
     22         }
     23         L->Next = NULL;  // 非常重要
     24     }
     25     return L;
     26 }
     27 
     28 int IsEmpty(List L)
     29 {
     30     return L->Next == NULL;
     31 }
     32 
     33 int IsLast(Position P, List L)
     34 {
     35     return P->Next == NULL;
     36 }
     37 
     38 // 查找
     39 Position Find(ElementType X, List L)
     40 {
     41     Position P;
     42     P = L->Next;
     43     while(P != NULL && P->Element != X)
     44         P = P->Next;
     45     return P;
     46 }
     47 
     48 // 删除, 注意先判断待删除的元素是否在链表中
     49 void Delete(ElementType X, List L)
     50 {
     51     Position P = FindPrevious(X, L);// 获得待删除元素的前驱
     52 
     53     if( !IsLast(P, L) ) // 如果X的前驱P是最后一个元素, 则表示L中无X
     54     {
     55         Position Q = P->Next;
     56         P->Next = Q->Next;
     57         free(Q);
     58     }
     59 }
     60 
     61 // 查找前驱, 注意区分Find操作与FindPrevious的区别是P的初始值不同
     62 Position FindPrevious(ElementType X, List L)
     63 {
     64     Position P;
     65     P = L;
     66     while(P->Next != NULL && P->Next->Element != X)
     67         P = P->Next;
     68     return P;
     69 }
     70 
     71 // 插入, 在P之后插入
     72 void Insert(ElementType X, List L, Position P)
     73 {
     74     Position TmpCell;
     75     // 先创建一个新节点
     76     TmpCell = (List)malloc( sizeof(struct Node) );
     77     if(TmpCell == NULL)
     78     {
     79         exit(-1);
     80     }
     81 
     82     TmpCell->Element = X;
     83     TmpCell->Next = P->Next;
     84     P->Next = TmpCell;
     85 }
     86 
     87 // 销毁链表, 需要两个指针
     88 void DeleteList(List L)
     89 {
     90     Position P, Q;
     91 
     92     P = L->Next; // 重要, 保留头节点
     93     L->Next = NULL;
     94     while(P != NULL)
     95     {
     96         Q = P->Next;
     97         free(Q);
     98         P = Q;
     99     }
    100 }
    101 
    102 Position Header(List L)
    103 {
    104     return L;
    105 }
    106 
    107 Position First(List L)
    108 {
    109     return L->Next;
    110 }
    111 
    112 Position Advance(Position P)
    113 {
    114     return P->Next;
    115 }
    116 
    117 ElementType Retrieve(Position P)
    118 {
    119     return P->Element;
    120 }
    121 
    122 void PrintElement(ElementType X)
    123 {
    124     printf("%d ", X);
    125 }
    126 
    127 // 递归遍历链表
    128 void TraversList(List L)
    129 {
    130     if(L != NULL)
    131     {
    132         PrintElement(L->Element);
    133         TraversList(L->Next);
    134     }
    135 }
    136 
    137 // 递归反向打印链表
    138 void ReverseTraversList(List L)
    139 {
    140     if(L != NULL)
    141     {
    142         ReverseTraversList(L->Next);
    143         PrintElement(L->Element);
    144     }
    145 }
    146 
    147 void TraverseL(List L)
    148 {
    149     top:
    150         if(L != NULL)
    151         {
    152             PrintElement(L->Element);
    153             L = L->Next;
    154             goto top;
    155         }
    156 }
    157 
    158 // 遍历链表, 非递归实现, 推荐
    159 void TraverseL2(List L)
    160 {
    161     while(L != NULL)
    162     {
    163         PrintElement(L->Element);
    164         L = L->Next;
    165     }
    166 }

    测试文件

     1 #include "list.h"
     2 #include <stdio.h>
     3 
     4 void
     5 PrintList( const List L )
     6 {
     7     Position P = Header( L );
     8 
     9     if( IsEmpty( L ) )
    10         printf( "Empty list
    " );
    11     else
    12     {
    13         do
    14         {
    15             P = Advance( P );
    16             printf( "%d ", Retrieve( P ) );
    17         } while( !IsLast( P, L ) );
    18         printf( "
    " );
    19     }
    20 }
    21 
    22 void TraverseList(const List L)
    23 {
    24     Position P = Header(L);
    25     if( IsEmpty(L) )
    26         printf("链表为空
    ");
    27     else
    28     {
    29         do
    30         {
    31             P = Advance(P);
    32             printf("%d ", Retrieve(P));
    33         } while( !IsLast(P, L) );
    34         printf("
    ");
    35     }
    36 }
    37 
    38 main( )
    39 {
    40     List L;
    41     Position P;
    42     int i;
    43 
    44     L = MakeEmpty( NULL );
    45     P = Header( L );
    46     // TraverseList( L );
    47     TraverseList(L);
    48 
    49     for( i = 0; i < 10; i++ )
    50     {
    51         Insert( i, L, P );
    52         TraverseList( L );
    53         P = Advance( P );
    54     }
    55     for( i = 0; i < 10; i+= 2 )
    56         Delete( i, L );
    57 
    58     for( i = 0; i < 10; i++ )
    59         if( ( i % 2 == 0 ) == ( Find( i, L ) != NULL ) )
    60             printf( "Find fails
    " );
    61 
    62     printf( "Finished deletions
    " );
    63 
    64     TraverseList( L );
    65     TraversList( Advance(L) );
    66     printf("
    ");
    67     ReverseTraversList( Advance(L) );
    68     printf("
    ");
    69     TraverseL( Advance(L) );
    70     printf("
    ");
    71     TraverseL2( Advance(L) );
    72     printf("
    ");
    73 
    74     DeleteList( L );
    75 
    76     return 0;
    77 }
  • 相关阅读:
    UWP开发之Mvvmlight实践一:如何在项目中添加使用Mvvmlight(图文详解)
    poj2909 欧拉素数筛选
    南京区域赛总结
    poj 2551 Ones
    poj 2524 Ubiquitous Religions(简单并查集)
    poj 2503 Babelfish(字典树或map或哈希或排序二分)
    poj 3080 Blue Jeans
    hdoj 4762 Cut the Cake
    linux tar.gz zip 解压缩 压缩命令
    poj 3714 寻找最近点对
  • 原文地址:https://www.cnblogs.com/moon1992/p/7500056.html
Copyright © 2011-2022 走看看