博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(2)数据结构——线性表(链表)实现
阅读量:4447 次
发布时间:2019-06-07

本文共 13803 字,大约阅读时间需要 46 分钟。

带头结点的单链表实现

LinkList.h

1 /*********************************************************************  2 *:  3 *:            Author: dspeeding  4 *:          Copyright (c) 2013, dspeeding  5 *:  6 *:        Created at: 2013.08.06  7 *:     Last modified: 2013.08.06    8 *:               9 *:      Introduction: 线性表链式实现 10 *: 11 *:    注:ElemType类型 不能进行深拷贝,请留意 12 *:  如使用 TraverseList 函数 则需要自己实现Visit函数 13 *:    如使用 SortList 函数 则需要自己实现Compare函数 14 *:    SortList 使用简单冒泡排序算法实现 15 *: 16 *:*********************************************************************/ 17 #include 
18 #include
19 #include
20 21 //定义数据类型为int型 22 typedef int ElemType; 23 24 25 typedef struct LNode{ 26 ElemType data; //数据 27 struct LNode *next; //下一指针 28 }LNode; 29 30 typedef LNode* LinkList; 31 typedef LinkList* PLinkList; 32 33 //定义数据类型的打印函数 34 typedef void (*Visit)(ElemType*); 35 36 //定义数据类型的比较函数 37 typedef int (*Compare)(ElemType*, ElemType*); 38 39 /**************************************** 40 Purpose : 初始化线性表 41 Input : L -- 线性表指针 42 Return : 0 --OK 43 -1 --FAIL 44 *****************************************/ 45 int InitList(PLinkList L); 46 47 48 /**************************************** 49 Purpose : 清空链表 50 Input : L -- 线性表指针 51 Return : None 52 *****************************************/ 53 void ClearList(PLinkList L); 54 55 /**************************************** 56 Purpose : 线性表长度 57 Input : L -- 线性表指针 58 Return : 线性表长度 如果是-1,则表示出错 59 *****************************************/ 60 int ListLength(PLinkList L); 61 62 /**************************************** 63 Purpose : 取链表中第nPos个元素 64 Input : L -- 线性表指针 65 nPos -- 位置 66 val -- 要取到的元素 67 Return : 0 --OK 68 -1 --FAIL 69 *****************************************/ 70 int GetElem(PLinkList L, int nPos, ElemType *val); 71 72 /**************************************** 73 Purpose : 在线性表中第nPos个位置插入新元素 74 Input : L -- 线性表指针 75 nPos -- 位置[1,ListLength(L)+1] 76 val -- 要插入的元素 77 Return : 0 --OK 78 -1 --FAIL 79 *****************************************/ 80 int InsertList(PLinkList L, int nPos, ElemType *val); 81 82 /**************************************** 83 Purpose : 在线性表中第nPos个位置删除元素 84 Input : L -- 线性表指针 85 nPos -- 位置[1,ListLength(L)] 86 val -- 数据 87 Return : 0 --OK 88 -1 --FAIL 89 *****************************************/ 90 int DeleteList(PLinkList L, int nPos, ElemType *val); 91 92 /**************************************** 93 Purpose : 返回线性表中第一个与e相等的数据元素的位序 94 Input : L -- 线性表指针 95 val -- 数据 96 compare -- 比较函数的函数指针 97 Return : 索引值,如果没有找到则返回-1 98 *****************************************/ 99 int LocateElem(PLinkList L, ElemType *val, Compare compare);100 101 102 /****************************************103 Purpose : 遍历输出线性表中每个元素104 Input : L -- 线性表指针105 visit -- 遍历函数指针106 Return : None107 *****************************************/108 void TraverseList(PLinkList L, Visit visit);109 110 /****************************************111 Purpose : 更新第nPos个位置元素112 Input : L -- 线性表指针113 nPos -- 元素的位置 [1, ListLength[L]]114 data -- 要更新的元素115 Return : 0 --OK116 -1 --FAIL117 *****************************************/118 int UpdateList(PLinkList L, int nPos, ElemType* val);119 120 121 /****************************************122 Purpose : 对线性表进行排序123 Input : L -- 线性表指针124 compare -- 比较函数125 Return : 0 --OK126 -1 --FAIL127 *****************************************/128 int SortList(PLinkList L, Compare compare);129 130 /****************************************131 Purpose : 对线性表进行逆置132 Input : L -- 线性表指针133 compare -- 比较函数134 Return : 0 --OK135 -1 --FAIL136 *****************************************/137 int ReverseList(PLinkList L);

LinkList.c

1 #include "LinkList.h"  2   3   4 /****************************************  5  Purpose :     初始化线性表  6  Input   :     L            -- 线性表指针  7  Return  :     0            --OK  8             -1            --FAIL  9 *****************************************/ 10 int InitList(PLinkList L) 11 { 12     //带头结点的单链表 13     *L = (LinkList)malloc(sizeof(LNode)); 14     if(!*L) 15     { 16         return -1; 17     } 18     (*L)->next = NULL; 19     return 0; 20 } 21  22 /**************************************** 23  Purpose :     清空链表 24  Input   :     L            -- 线性表指针 25  Return  :     None 26 *****************************************/ 27 void ClearList(PLinkList L) 28 { 29     LinkList p = *L; 30     while((*L)->next) 31     { 32         p=p->next; 33         free(*L); 34         *L = p; 35     } 36     (*L)->next = NULL; 37 } 38  39 /**************************************** 40  Purpose :     线性表长度 41  Input   :     L            -- 线性表指针 42  Return  :     线性表长度   如果是-1,则表示出错 43 *****************************************/ 44 int ListLength(PLinkList L) 45 { 46     LinkList p = NULL; 47     int nLen = 0; 48     if(*L == NULL) 49     { 50         return -1; 51     } 52     p = (*L)->next; 53     while(p) 54     { 55         p = p->next; 56         nLen++; 57     } 58     return nLen; 59 } 60  61 /**************************************** 62  Purpose :     取链表中第nPos个元素 63  Input   :     L            -- 线性表指针 64             nPos        -- 位置 65             val            -- 要取到的元素 66  Return  :     0            --OK 67             -1            --FAIL 68 *****************************************/ 69 int GetElem(PLinkList L, int nPos, ElemType *val) 70 { 71     LinkList p = *L; 72     int i = 0; 73     if(nPos > ListLength(L) || nPos < 0) 74     { 75         return -1; 76     } 77     while(i < nPos && p) 78     { 79         p = p->next; 80         i++; 81     } 82     memcpy(val, &p->data, sizeof(ElemType)); 83     return 0; 84 } 85  86 /**************************************** 87  Purpose :     在线性表中第nPos个位置插入新元素 88  Input   :     L            -- 线性表指针 89             nPos        -- 位置  [1,ListLength(L)+1] 90             val            -- 要插入的元素 91  Return  :     0            --OK 92             -1            --FAIL 93 *****************************************/ 94 int InsertList(PLinkList L, int nPos, ElemType *val) 95 { 96     LinkList p = *L; 97     LinkList q = NULL; 98     int i = 0; 99     int nLen = ListLength(L);100     if(nPos < 1|| nPos > nLen+1)101     {102         return -1;103     }104     q = (LinkList)malloc(sizeof(LNode));105     if(q == NULL)106     {107         return -1;108     }109     while(i < nPos - 1)110     {111         p = p->next;112         i++;113     }114     115     memcpy(&q->data, val, sizeof(ElemType));116     q->next = p->next;117     p->next = q;118     return 0;119 }120 121 /****************************************122  Purpose :     在线性表中第nPos个位置删除元素123  Input   :     L            -- 线性表指针124             nPos        -- 位置[1,ListLength(L)]125             val            -- 数据126  Return  :     0            --OK127             -1            --FAIL128 *****************************************/129 int DeleteList(PLinkList L, int nPos, ElemType *val)130 {131     LinkList p = *L;132     LinkList q = NULL;133     int i;134     if(nPos < 1 || nPos > ListLength(L))135     {136         return -1;137     }138     while(i < nPos -1)139     {140         p = p->next;141         i++;142     }143     q = p->next;144     p->next = q->next;145     memcpy(val, &q->data, sizeof(ElemType));146     free(q);147     q = NULL;148     return 0;149 }150 151 152 /****************************************153  Purpose :     返回线性表中第一个与e相等的数据元素的位序154  Input   :     L            -- 线性表指针155             val            -- 数据156             compare        -- 比较函数的函数指针157  Return  :     索引值,如果没有找到则返回-1158 *****************************************/159 int LocateElem(LinkList *L, ElemType *val, Compare compare)160 {161     LinkList p = NULL;162     int i = 1;163     if(*L == NULL)164     {165         return -1;166     }167     p = (*L)->next;168     while(p && compare(val, &p->data) != 0)169     {170         p = p->next;171         i++;172     }173     if(p == NULL)174     {175         return -1;176     }177     return i;178 }179 180 181 /****************************************182  Purpose :     遍历输出线性表中每个元素183  Input   :     L            -- 线性表指针184             visit        -- 遍历函数指针185  Return  :     None186 *****************************************/187 void TraverseList(PLinkList L, Visit visit)188 {189     LinkList p = NULL;190     if(*L != NULL)191     {192         p = (*L)->next;193         while(p != NULL)194         {195             visit(&p->data);196             p = p->next;197         }198     }199 }200 201 /****************************************202  Purpose :     更新第nPos个位置元素203  Input   :     L            -- 线性表指针204             nPos        -- 元素的位置  [1, ListLength[L]]205             data        -- 要更新的元素206  Return  :     0            --OK207             -1            --FAIL208 *****************************************/209 int UpdateList(PLinkList L, int nPos, ElemType* val)210 {211     int i = 0;212     LinkList p = NULL;213     if(nPos < 1 && nPos > ListLength(L))214     {215         return -1;216     }217     p = *L;218     while(i < nPos)219     {220         p = p->next;221         i++;222     }223     224     memcpy(&p->data, val, sizeof(ElemType));225     return 0;226 }227 228 229 230 /****************************************231  Purpose :     对线性表进行排序232  Input   :     L            -- 线性表指针233             compare        -- 比较函数234  Return  :     0            --OK235             -1            --FAIL236 *****************************************/237 int SortList(PLinkList L, Compare compare)238 {239     LinkList p = NULL;240     LinkList q = NULL;241     ElemType tmp;242     if(*L == NULL)243     {244         return -1;245     }246     for(p = (*L)->next;p!=NULL;p=p->next)247     {248         for(q=p->next;q!=NULL;q=q->next)249         {250             if(compare(&q->data, &p->data) < 0)251             {252                 memcpy(&tmp, &q->data, sizeof(ElemType));253                 memcpy(&q->data, &p->data, sizeof(ElemType));254                 memcpy(&p->data, &tmp, sizeof(ElemType));255             }256         }257     }258     return 0;259 }260 261 /****************************************262  Purpose :     对线性表进行逆置263  Input   :     L            -- 线性表指针264             compare        -- 比较函数265  Return  :     0            --OK266             -1            --FAIL267 *****************************************/268 int ReverseList(PLinkList L)269 {270     LinkList p = NULL;271     LinkList q = NULL;272     LinkList s = NULL;273     if(*L == NULL)274     {275         return -1;276     }277     p = (*L)->next;278     if(p == NULL)279     {280         //没有数据则返回正确281         return 0;282     }283     q = p->next;284     while(q->next != NULL)285     {286         s = q->next;287         q->next = p;288         p = q;289         q = s;290     }291     q->next = p;                //最后一个节点的next调整下292     (*L)->next->next = NULL;    //保留头结点293     (*L)->next = q;294     return 0;295 }

testmain.c

1 #include 
2 #include "LinkList.h" 3 4 void visit(ElemType *val) 5 { 6 printf("%3d ", *val); 7 } 8 int compare(ElemType* e1, ElemType* e2) 9 {10 return *e1 - *e2;11 }12 int main(int argc, char* argv[])13 {14 LinkList L;15 int i;16 ElemType val;17 printf("初始化线性表\n");18 if(InitList(&L))19 {20 printf("初始化线性表失败\n");21 return -1;22 }23 printf("插入数据1\n");24 val = 3;25 if(InsertList(&L, 1, &val))26 {27 printf("插入线性表数据失败\n");28 }29 printf("插入数据2\n");30 val = 200;31 if(InsertList(&L, 1, &val))32 {33 printf("插入线性表数据失败\n");34 }35 val = -1;36 if(InsertList(&L, 1, &val))37 {38 printf("插入线性表数据失败\n");39 }40 for(i=0;i<8;i++)41 {42 val = i;43 if(InsertList(&L, 1, &val))44 {45 printf("插入线性表数据失败\n");46 }47 }48 TraverseList(&L, visit);49 /*val = 555;50 if(InsertList(&L, ListLength(&L), &val))51 {52 printf("插入线性表数据失败\n");53 }54 TraverseList(&L, visit);55 printf("排序数据\n");56 SortList(&L, compare);57 TraverseList(&L, visit);58 printf("获取数据\n");59 if(GetElem(&L, 1, &val))60 {61 printf("获取数据失败\n");62 }63 visit(&val);*/64 /*int nLen = ListLength(&L);65 printf("线性表长度[%d]\n", nLen);66 printf("删除数据\n");67 if(DeleteList(&L, nLen, &val))68 {69 printf("删除数据失败\n");70 }71 TraverseList(&L, visit);72 printf("删除的数据为\n");73 visit(&val);74 printf("更新数据\n");75 val = 1000;76 if(UpdateList(&L, 2, &val))77 {78 printf("更新数据失败\n");79 }80 TraverseList(&L, visit);81 82 val = 555;83 int nIndex = LocateElem(&L, &val, compare);84 printf("定位数据位置为[%d]\n", nIndex);85 */86 printf("\n逆置链表\n");87 if(ReverseList(&L))88 {89 printf("逆置失败\n");90 }91 TraverseList(&L, visit);92 printf("\n");93 ClearList(&L);94 return 0;95 }

 

转载于:https://www.cnblogs.com/dspeeding/p/3240584.html

你可能感兴趣的文章
linux性能优化实战-网络性能调优
查看>>
AMQ7017 日志不可用.
查看>>
linux下将编译错误输出到一个文本文件
查看>>
webpack.config.js配置遇到Error: Cannot find module '@babel/core'问题
查看>>
NLP基本任务-nltk_data文本分割
查看>>
WPF 碰撞检测
查看>>
个性化设置
查看>>
Spring中@Resource与@Autowired、@Qualifier的用法与区别(转)
查看>>
HDU1565(状态压缩dp)
查看>>
docker记录
查看>>
Mysql 使用cmd运行sql脚本
查看>>
简单模板类
查看>>
HALCON标定板制作方法
查看>>
PAT 天梯赛 L1-009 N个数求和
查看>>
编码与解码
查看>>
java集合框架概述
查看>>
HP Vitrual Connect 配置快速参考
查看>>
ORA-04021等待锁定对象时超时
查看>>
Android学习笔记-事件处理机制
查看>>
阮一峰:为什么要写博客(转)
查看>>