-
链表(链式存储)
-
单链表
-
定义(如何用代码实现)
-
什么是单链表
-
-
-
优点:不要求大片连续空间,改变容量方便
缺点:不可随机存取,要耗费一定空间存放指针
-
用代码定义一个单链表
struct LNode{ //结点;定义单链表结点类型 ElemType data; //数据域;每个结点存放一个数据元素 struct LNdode *next; //指针域;指针指向下一个结点 } //增加一个新的结点:在内存中申请一个结点所需空间,并用指针p指向这个结点 //struct LNode *p = (struct LNode *) malloc(sizeof(struct LNode)); //优化 typedef struct LNode LNode; LNode * p = (LNode *)malloc(sizeof(LNode));
typedef 关键字 —— 数据类型重命名
typedef <数据类型><别名>
typedef struct LNode{ //定义单链表结点类型 ElemType data; //每个结点村南方一个数据元素 struct LNode *next; //指针指向下一个结点 }LNode, *LinkList; struct LNode{ //定义单链表结点类型 ElemType data; //每个结点存放一个数据元素 struct LNdode *next; //指针指向下一个结点 } typedef struct LNode LNode; typedef struct LNode *LinkList;
要表示一个单链表时,只需声明一个头指针L,指向单链表的第一个结点。
LNode * L; //方法一:声明一个指向单链表第一个结点的指针 //代码可读性更强 ↓ LinkList L; //方法二:声明一个指向单链表第一个结点的指针
🌲 例子:
-
typedef struct LNode{ //定义单链表结点类型 ElemType data; //每个结点村南方一个数据元素 struct LNode *next; //指针指向下一个结点 }LNode, *LinkList; LNode * GetElem(LinkList L,int i){ int j = 1; LNode * p = L -> next; if(i == 0) return L; if(i < 1) return NULL; while(p != NULL && j < i){ p = p -> next; j++ } return p; }
强调这是一个单链表 —— 使用LinkList
强调这是一个结点 ——使用LNode *
-
两种实现
-
带头结点 (写代码更方便)
typedef struct LNode{ //定义单链表结点类型 ElemType data; //每个结点村南方一个数据元素 struct LNode *next; //指针指向下一个结点 }LNode, *LinkList; //初始化一个单链表(带头结点) bool InitList(LinkList &L){ L = (LNode *) malloc(sizeif(LNode)); //分配一个头节点 if (L == NULL) //内存不足,分配失败 return false; L -> next = NULL; //头节点之后暂时还没有结点 return true; } //判断单链表是否为空(带头结点) bool Empty(LinkList L){ if (L -> next == NULL) return true; else return false; } void test(){ //注意,此处并没有创建一个结点 LinkList L; //声明一个指向单链表的指针 //初始化一个空表 InitList(L); //...后续代码... }
-
不带头结点
-
-
typedef struct LNode{ //定义单链表结点类型 ElemType data; //每个结点村南方一个数据元素 struct LNode *next; //指针指向下一个结点 }LNode, *LinkList; //初始化一个空的单链表 bool InitList(LinkList &L){ L = NULL; //空表,暂时还没有任何结点(防止脏数据) return true; } //判断单链表是否为空 bool Empty(LinkList L){ return (L == NULL) } void test(){ //注意,此处并没有创建一个结点 LinkList L; //声明一个指向单链表的指针 //初始化一个空表 InitList(L); //...后续代码... }