zoukankan      html  css  js  c++  java
  • 单链表操作

     1 #ifndef LIST_H
     2 #define LIST_H
     3 
     4 typedef unsigned int Item;  
     5 typedef unsigned char byte;  
     6 struct node  
     7 {  
     8   Item item;    // 卫星数据   
     9   struct node * next;  
    10 };  
    11 typedef struct node * List;           
    12 
    13 void ListAddItem(List *plist, const Item item);
    14 struct node * ListSearchItem(const List list, const Item item);
    15 void ListDelItem(List *plist, const Item item);
    16 void ListDel(List *plist);
    17 void ListInvert(List *plist);
    18 bool ListIsLoop(const List list);
    19 struct node * ListConcatenate(List list1, List list2);
    20 #endif
      1 #include "stdafx.h"
      2 #include "list.h"
      3 #include <assert.h>
      4 #include <malloc.h>
      5 
      6 static inline void CopyItem(Item item, struct node* pnode)  
      7 {  
      8     pnode->item = item;    
      9 }  
     10 
     11 static inline int ItemCmp(Item item1, Item item2)  
     12 {  
     13     return item1 > item2 ? 1 : (item1 == item2 ? 0 : -1);
     14 }  
     15 
     16 
     17 /**********************************************
     18     向链表中插入节点
     19     当链表为空时,需要改变链表头所指向的内容,因此入参用链表头指针
     20 **********************************************/
     21 void ListAddItem(List *plist, const Item item)
     22 {
     23     assert(NULL != plist);
     24 
     25     struct node *pnew;
     26     pnew = (struct node *)malloc(sizeof(struct node));  
     27     assert(NULL != pnew);
     28     
     29     CopyItem(item,pnew); 
     30 
     31     // 从小到大排列
     32     struct node *pscan = *plist;
     33     struct node *pinsert = NULL;
     34     while (NULL != pscan)
     35     {
     36         // 若是只需要插入到链表尾,可以去掉if-else条件,将循环体改为
     37         // pinsert = pscan; pscan = pscan->next;
     38         if (ItemCmp(pscan->item, item) < 0)
     39         {
     40             pinsert = pscan;
     41             pscan = pscan->next;
     42         }
     43         else
     44         {
     45             break;  
     46         }
     47     }
     48     
     49     // 无比item小的节点或是空链表,链表头插入
     50     if (NULL == pinsert)
     51     {
     52         pnew->next = pscan;
     53         *plist = pnew;
     54     }
     55     else    // 链表中间或者链表尾部
     56     {
     57         pnew->next = pscan;
     58         pinsert->next = pnew;
     59     }
     60 }
     61 
     62 /**********************************************   
     63  若相应的item存在,则返回第一个item的前驱(头节点的
     64  前驱为NULL)
     65  否则返回NULL
     66 **********************************************/ 
     67 struct node * ListSearchItem(const List list, const Item item)
     68 {
     69     struct node * pscan = list;
     70     struct node * pprev = NULL;
     71 
     72     while (NULL != pscan)
     73     {
     74         if (ItemCmp(pscan->item, item) == 0)
     75         {
     76             return pprev;    
     77         }
     78         else
     79         {
     80             pprev = pscan;
     81             pscan = pscan->next;
     82         }
     83     }
     84 
     85     return NULL;
     86 }
     87 
     88 
     89 /**********************************************    
     90 // 删除元素   
     91 // 返回值:0,删除失败(不存在该item),1:删除成功   
     92 **********************************************/ 
     93 void ListDelItem(List *plist, const Item item)
     94 {
     95     assert(NULL != plist);
     96     
     97     struct node *ptemp = *plist;
     98     if (NULL == ptemp)  // 空链表
     99         return;
    100     
    101     struct node *pdel = ListSearchItem(*plist, item); 
    102     if (NULL == pdel)
    103     {
    104         if (ItemCmp((*plist)->item, item) == 0)
    105         {
    106             pdel = *plist;
    107             *plist = pdel->next;
    108             free(pdel);
    109         }
    110     }
    111     else
    112     {
    113         ptemp = pdel->next;  // item所在节点   
    114         pdel->next = pdel->next->next;  
    115         free(ptemp);     
    116     }
    117 }
    118 
    119 
    120 /**********************************************   
    121 // 删除链表   
    122 **********************************************/ 
    123 void ListDel(List *plist)
    124 {
    125     assert(NULL != plist);
    126 
    127     struct node *pscan;
    128     struct node *pdel;
    129 
    130     pscan = *plist;
    131 
    132     while (NULL != pscan)
    133     {
    134         pdel = pscan;
    135         pscan = pscan->next;
    136         free(pdel);
    137     }
    138     
    139     *plist = NULL;
    140 }
    141 
    142 /**********************************************
    143     单链表翻转:采用3个指针就地翻转
    144 **********************************************/
    145 void ListInvert(List *plist)
    146 {
    147     assert(NULL != plist);
    148 
    149     struct node *head, *tail, *pscan;
    150 
    151     head = NULL;
    152     pscan = *plist;
    153 
    154     while (pscan)
    155     {
    156         tail = head;
    157         head = pscan;
    158         pscan = pscan->next;
    159         head->next = tail;
    160     }
    161 
    162     *plist = head;
    163 }
    164 
    165 /**********************************************
    166  检查单链表是否有环:
    167     采用2个指针以不同的步长移动,若有环,则快的一定
    168  能追上慢的
    169 **********************************************/
    170 bool ListIsLoop(const List list)
    171 {
    172     struct node *fast;   
    173     struct node *slow;
    174 
    175     if (NULL == list)
    176         return false;
    177     
    178     slow = list;
    179     fast = list->next;
    180 
    181     while (NULL != fast)
    182     {
    183         if (slow == fast)
    184             return true;
    185 
    186         slow = slow->next;
    187         
    188         fast = fast->next;
    189         if (NULL == fast)
    190             return false;
    191         fast = fast->next;
    192     }
    193 
    194     return false;
    195 }
    196 
    197 /**********************************************
    198 串接2个单链表:
    199     将list2串接到list1之后,返回串接后的链表头
    200 **********************************************/
    201 struct node * ListConcatenate(List list1, List list2)
    202 {
    203     struct node *ptemp;
    204 
    205     if (NULL == list1)
    206         return list2;
    207     
    208     ptemp = list1;
    209     while (NULL != ptemp->next)
    210         ptemp = ptemp->next;
    211 
    212     ptemp->next = list2;
    213 
    214     return list1;
    215 }
    216 
    217 /**********************************************
    218  判断两个链表是否相交:
    219     将两个链表串接起来,判断是否有环
    220 **********************************************/
  • 相关阅读:
    【转】HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别
    【转】ArrayList循环遍历并删除元素的常见陷阱
    【转】Java内存管理:深入Java内存区域
    【转】java-String中的 intern()
    Jenkins + Ant + Git + Tomcat自动化部署
    Java的四种内部类
    java中的匿名内部类总结
    【转】如何提高意志力&如何坚持每天学习
    【转】前端工程筹建NodeJs+gulp+bower
    转 旧衣服不要扔,竟然还能这样改造,美翻了!
  • 原文地址:https://www.cnblogs.com/wangzhijun/p/3173546.html
Copyright © 2011-2022 走看看