数据结构(14)单链表

来源:互联网 发布:阿里云 虚拟主机 美国 编辑:程序博客网 时间:2024/06/06 19:59

用一组地址任意的存储单元存放线性表中的数据元素,以元素(数据元素的映象) + 指针(指示后继元素存储位置)= 结点(表示数据元素 或 数据元素的映象),以“结点的序列”表示线性表称作线性链表(单链表)。

       有几个基本概念需要掌握,如下:

             1.表头结点

                    链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息。

             2.数据结点

                    链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息

             3.尾结点

                    链表中的最后一个数据结点,其下一元素指针为空,表示无后继

             这里主要介绍线性表的常用操作:

                     l 创建线性表

                     l 销毁线性表

                     l 清空线性表

                     l 将表中元素倒置

                     l 表元素插入

                     l 表元素删除

                     l 获取表中某个位置的元素

                     l 获取表长度

              

             代码总分为三个文件:

                           LinkList.h : 放置功能函数的声明,以及表的声明,表结点的定义 

                           LinkList.c : 放置功能函数的定义,以及表的定义

                           Main.c      : 主函数,使用功能函数完成各种需求,不过一般用作测试

 

            这里着重说下插入操作﹑删除操作和倒置操作:

                    插入操作:

                            如图

                           

                    插入元素方法:

                            首先判断线性表﹑插入位置是否合法

                            由表头开始通过next指针移动pos次后,当前元素的next指针即指向要插入的位置

                            把当前元素(current)的next指针包含的地址赋给新元素(node)的next指针

                            把新元素(node)的地址赋给当前元素(current)的next指针

                            最后把线性表长度加1

                   删除操作:

                          如图

                                    

                   删除元素方法:

                          首先判断线性表﹑删除位置是否合法

                          获取第pos个元素

                         将第pos个元素的next指针保存的地址赋给第pos个元素前一个元素的next指针

                         最后把表长度减1

 

                      倒置操作:

                         如图

                            

                倒置元素方法:

                        把头结点指向的首元素的next指针赋为NULL

                        然后把首元素以后的结点依次每个插入到头结点和首元素中间

 

OK! 上代码:

LinkList.h

[cpp] view plaincopy
  1. #ifndef _LINKLIST_H_  
  2. #define _LINKLIST_H_  
  3.   
  4. typedef void LinkList;  
  5. typedef struct _tag_LinkListNode LinkListNode;  
  6.   
  7. struct _tag_LinkListNode  
  8. {  
  9.     LinkListNode* next;  
  10. };  
  11.   
  12. LinkList* LinkList_Create();  
  13.   
  14. void LinkList_Destroy(LinkList* list);  
  15.   
  16. void LinkList_Clear(LinkList* list);  
  17.   
  18. void LinkList_Reverse(LinkList* list);  
  19.   
  20. int LinkList_Length(LinkList* list);  
  21.   
  22. int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);  
  23.   
  24. LinkListNode* LinkList_Get(LinkList* list, int pos);  
  25.   
  26. LinkListNode* LinkList_Delete(LinkList* list, int pos);  
  27.   
  28. #endif  


LInkList.c

 

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <malloc.h>  
  3. #include "LinkList.h"  
  4.   
  5. typedef struct _tag_LinkList  
  6. {  
  7.     LinkListNode header;  
  8.     int length;  
  9. }TLinkList;  
  10.   
  11. LinkList* LinkList_Create()  
  12. {  
  13.     TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));  
  14.   
  15.     if(ret != NULL)  
  16.     {  
  17.         ret->length = 0;  
  18.         ret->header.next = NULL;  
  19.     }  
  20.   
  21.     return ret;  
  22. }  
  23.   
  24. void LinkList_Destroy(LinkList* list)  
  25. {  
  26.     free(list);  
  27. }  
  28.   
  29. void LinkList_Clear(LinkList* list)  
  30. {  
  31.     TLinkList* sList = (TLinkList*)list;  
  32.   
  33.     if(sList!=NULL)  
  34.     {  
  35.         sList->header.next = NULL;  
  36.         sList->length = 0;  
  37.     }  
  38. }  
  39.   
  40. void LinkList_Reverse(LinkList* list)  
  41. {  
  42.     TLinkList* sList = (TLinkList*)list;  
  43.       
  44.     if((sList!=NULL)&&(sList->length>1))  
  45.     {  
  46.         LinkListNode* current = (LinkListNode*)sList;  
  47.         LinkListNode* p = current->next;  
  48.         LinkListNode* q = current->next;  
  49.           
  50.         q = q->next;  
  51.         p->next = NULL;  
  52.         p = q;  
  53.           
  54.         (p != NULL)  
  55.         {  
  56.             q = q->next;  
  57.             p->next = current->next;  
  58.             current->next = p;  
  59.             p = q;  
  60.         }  
  61.     }  
  62. }  
  63.   
  64. int LinkList_Length(LinkList* list)  
  65. {  
  66.     TLinkList* sList = (TLinkList*)list;  
  67.   
  68.     int ret = -1;  
  69.   
  70.     if(sList!=NULL)  
  71.     {  
  72.         ret = sList->length;  
  73.     }  
  74.   
  75.     return ret;  
  76. }  
  77.   
  78. int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)  
  79. {  
  80.     TLinkList* sList = (TLinkList*)list;  
  81.   
  82.     int ret = (sList!=NULL) && (pos>=0) && (node!=NULL);  
  83.       
  84.     int i = 0;  
  85.   
  86.     if(ret)  
  87.     {  
  88.         if(pos >= sList->length)  
  89.         {  
  90.             pos = sList->length;  
  91.         }  
  92.   
  93.         LinkListNode* current = (LinkListNode*)sList;  
  94.   
  95.         for(i=0; (i<pos)&&(current->next!=NULL); i++)  
  96.         {  
  97.             current = current->next;  
  98.         }  
  99.   
  100.         node->next = current->next;  
  101.   
  102.         current->next = node;  
  103.   
  104.         sList->length++;  
  105.     }  
  106.   
  107.     return ret;  
  108. }  
  109.   
  110. LinkListNode* LinkList_Get(LinkList* list, int pos)  
  111. {  
  112.     TLinkList* sList = (TLinkList*)list;  
  113.   
  114.     LinkListNode* ret =NULL;  
  115.   
  116.     int i = 0;  
  117.   
  118.     if((sList!=NULL)&&(pos>=0) && (pos<sList->length))  
  119.     {  
  120.         LinkListNode* current = (LinkListNode*)sList;  
  121.   
  122.         for(i=0; (i<pos)&&(current->next!=NULL); i++)  
  123.         {  
  124.             current = current->next;  
  125.         }  
  126.   
  127.         ret = current->next;  
  128.     }  
  129.   
  130.     return ret;  
  131. }  
  132.   
  133. LinkListNode* LinkList_Delete(LinkList* list, int pos)  
  134. {  
  135.     TLinkList* sList = (TLinkList*)list;  
  136.   
  137.     LinkListNode* ret = NULL;  
  138.   
  139.     int i = 0;  
  140.   
  141.     if((sList!=NULL)&&(pos>=0)&&(pos<sList->length))  
  142.     {  
  143.         LinkListNode* current = (LinkListNode*)sList;  
  144.   
  145.         for(i=0; i<pos; i++)  
  146.         {  
  147.             current = current->next;  
  148.         }  
  149.   
  150.         ret = current->next;  
  151.   
  152.         current->next = ret->next;  
  153.   
  154.         sList->length--;  
  155.     }  
  156.   
  157.     return ret;  
  158. }  


main.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "LinkList.h"  
  4.   
  5. typedef struct _tag_Value  
  6. {  
  7.     LinkListNode header;  
  8.     int v;  
  9. }Value;  
  10.   
  11. int main(void)  
  12. {  
  13.     LinkList* list = LinkList_Create();  
  14.   
  15.     int i = 0;  
  16.   
  17.     Value v1, v2, v3, v4, v5;  
  18.   
  19.     v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;  
  20.   
  21.     LinkList_Insert(list, (LinkListNode*)&v1, 0);  
  22.     LinkList_Insert(list, (LinkListNode*)&v2, 0);  
  23.     LinkList_Insert(list, (LinkListNode*)&v3, 0);  
  24.     LinkList_Insert(list, (LinkListNode*)&v4, 0);  
  25.     LinkList_Insert(list, (LinkListNode*)&v5, 0);  
  26.   
  27.     Value* pV = NULL;  
  28.   
  29.     for(i=0; i<LinkList_Length(list); i++)  
  30.     {  
  31.         pV = (Value*)LinkList_Get(list, i);  
  32.   
  33.         printf("%d\n", pV->v);  
  34.     }  
  35.   
  36.     while(LinkList_Length(list) > 0)  
  37.     {  
  38.         pV = (Value*)LinkList_Delete(list, LinkList_Length(list)-1);  
  39.   
  40.         printf("%d\n", pV->v);  
  41.     }  
  42.   
  43.     LinkList_Destroy(list);  
  44.   
  45.     return 0;  
  46. }  
0 0