单链表的实现
目录
1、链表
编辑编辑
2、实现
2.1 单链表存储结构
2.2链表—初始化
2.3单链表—头插法
2.4 链表遍历
2.5链表—尾插法
2.6 在指定的位置插入数据
2.7 删除指定位置的元素
2.8 释放单链表
2.9 销毁链表
2.10 判断链表是否为空
2.11 找到第i个元素
3、总代码—测试
1、链表
线性表链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。
为了表示每个数据元素ai与直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了其本身的信息之外,还需要存储一个指示其直接后继的信息(直接后继的存储位置)。这两部分信息组成数据元素ai的存储映像,称为节点(node)。
结点包括两个域:其中存储数据元素信息的称之为数据域;存储直接后继存储位置有域称之为指针域。指针域中存储的信息称作指针或者链
n个结点[ai(i <= i <= n)的存储映像]链接成一个链表,即为线性表(a1,a2....an)。
2、实现
2.1 单链表存储结构
typedef struct node {ElemType data;struct node* next;
}Node;
2.2链表—初始化
//链表的初始化
Node* initList() {Node* head = (Node*)malloc(sizeof(Node));head->data = 0;head->next = NULL;return head;
}
2.3单链表—头插法
在头结点后面插入结点
//链表—头插法
void insertHead(Node* L, ElemType e) {Node* p = (Node*)malloc(sizeof(Node));p->data = e;p->next = L->next;L->next = p;
2.4 链表遍历
//链表—遍历
void listNode(Node* L) {Node* p = L->next;while (p != NULL) {printf("%d ", p->data);p = p->next;}printf("\n");
}
2.5链表—尾插法
//链表—尾插法
//void insertend(Node* L, ElemType e) {
// Node* s = (Node*)malloc(sizeof(Node));
// s->data = e;
// s->next = NULL;
//
// Node* p = L; // 从头节点开始遍历
// while (p->next != NULL) { // 定位到最后一个非空节点
// p = p->next;
// }
// p->next = s; // 正确链接新节点
//}void insertend(Node* L, ElemType e) {Node* s = (Node*)malloc(sizeof(Node));Node* p = L;while (p->next != NULL) {p = p->next;}s->data = e;p->next = s;s->next = NULL;}
2.6 在指定的位置插入数据
//在指定是数据插入数据
bool Listlinsert(Node* L, int i, ElemType e) {int j = 0;if (i <= 0) {return false;}Node *p = L;//while找到插入位置的前一个节点while (j < i - 1) {p = p->next;j++;if (p == NULL) {return false;}}//s是要插入的新节点Node* s = (Node*)malloc(sizeof(Node));s->data = e;s->next = p->next;p->next = s; return true;
}
2.7 删除指定位置的元素
//删除第i个数据元素
bool ListDelete(Node* L, int i) {int j = 0;Node* d = L;//找到所删除结点的前一个节点while (j < i - 1) {d = d->next;j++;if (d == NULL) {return false;}}if (d->next == NULL) {return false;}Node* p = d->next;//这里的p指的是删除位置d->next = p->next;free(p);return true;}
2.8 释放单链表
//释放链表
void Slist(Node* L) {Node* per = L->next;Node* p;while (per != NULL) {p = per->next;free(per);per = p;}free(per);L->next = NULL;
}
2.9 销毁链表
//销毁链表
void DestroyList(Node* L) {Node* per = L;Node* p = L->next;while (per != NULL) {free(per);per = p;p = p->next;}free(per);
}
2.10 判断链表是否为空
//判断链表是否为空
bool ListEmpty(Node* L) {return (L->next == NULL);
}
2.11 找到第i个元素
//查找链表中第i个元素并将值赋给e
bool GetElem(Node* L, int i, ElemType* e) {int j = 0;Node* p = L;while (p->next != NULL) {if (i == j) {*e = p->data;return true;}j++;p = p->next;}return false;}
3、总代码—测试
linklist.h
#pragma once
#include<malloc.h>
#include<stdio.h>
#include<stdbool.h>
typedef int ElemType;typedef struct node {ElemType data;struct node* next;
}Node;//链表的初始化
Node* initList();//链表—头插法
void insertHead(Node* L, ElemType e);void listNode(Node* L);//链表—尾插法
void insertend(Node* L, ElemType e);//在指定位置插入
bool Listlinsert(Node* L, int i, ElemType e);//删除第i个数据元素
bool ListDelete(Node* L, int i);//获取链表的长度
int ListLength(Node* L);//释放链表
void Slist(Node* L);//销毁链表
void DestroyList(Node* L);//判断链表是否为空
bool ListEmpty(Node* L);//查找链表中第i个元素并将值赋给e
bool GetElem(Node* L, int i, ElemType* e);
linklist.c
#include "linklist.h"//链表的初始化
Node* initList() {Node* head = (Node*)malloc(sizeof(Node));head->data = 0;head->next = NULL;return head;
}//链表—头插法
void insertHead(Node* L, ElemType e) {Node* p = (Node*)malloc(sizeof(Node));p->data = e;p->next = L->next;L->next = p;
}//链表—遍历
void listNode(Node* L) {Node* p = L->next;while (p != NULL) {printf("%d ", p->data);p = p->next;}printf("\n");
}//链表—尾插法
//void insertend(Node* L, ElemType e) {
// Node* s = (Node*)malloc(sizeof(Node));
// s->data = e;
// s->next = NULL;
//
// Node* p = L; // 从头节点开始遍历
// while (p->next != NULL) { // 定位到最后一个非空节点
// p = p->next;
// }
// p->next = s; // 正确链接新节点
//}void insertend(Node* L, ElemType e) {Node* s = (Node*)malloc(sizeof(Node));Node* p = L;while (p->next != NULL) {p = p->next;}s->data = e;p->next = s;s->next = NULL;}//在指定是数据插入数据
bool Listlinsert(Node* L, int i, ElemType e) {int j = 0;if (i <= 0) {return false;}Node *p = L;//while找到插入位置的前一个节点while (j < i - 1) {p = p->next;j++;if (p == NULL) {return false;}}//s是要插入的新节点Node* s = (Node*)malloc(sizeof(Node));s->data = e;s->next = p->next;p->next = s; return true;
}//删除第i个数据元素
bool ListDelete(Node* L, int i) {int j = 0;Node* d = L;//找到所删除结点的前一个节点while (j < i - 1) {d = d->next;j++;if (d == NULL) {return false;}}if (d->next == NULL) {return false;}Node* p = d->next;//这里的p指的是删除位置//要删除结点的前驱指向要删除结点的后继d->next = p->next;free(p);return true;}//获取数据节点的长度(不包括头结点)
int ListLength(Node* L) {Node* p = L;int ans = 0;while (p->next != NULL) {ans += 1;p = p->next;}return ans;
}//释放链表
void Slist(Node* L) {Node* per = L->next;Node* p;while (per != NULL) {p = per->next;free(per);per = p;}free(per);L->next = NULL;
}//销毁链表
void DestroyList(Node* L) {Node* per = L;Node* p = L->next;while (per != NULL) {free(per);per = p;p = p->next;}free(per);
}//判断链表是否为空
bool ListEmpty(Node* L) {return (L->next == NULL);
}//查找链表中第i个元素并将值赋给e
bool GetElem(Node* L, int i, ElemType* e) {int j = 0;Node* p = L;while (p->next != NULL) {if (i == j) {*e = p->data;return true;}j++;p = p->next;}return false;}
test.c 测试
#include "linklist.h";int main() {Node* list = initList();//判断链表是否为空if (ListEmpty(list)) {printf("链表为空\n");}insertHead(list, 1);insertHead(list, 1);insertHead(list, 1);insertHead(list, 1);insertend(list, 5);Listlinsert(list, 3, 88);//删除第i个数据元素ListDelete(list, 4);//释放链表//Slist(list);//销毁链表//DestroyList(list);// //查找链表中第i个元素并将值赋给eElemType e = 0;if(GetElem(list, 6, &e)){printf("找到的元素为:%d\n", e);}else {printf("没找到第i个元素\n");}printf("链表中元素的个数:%d\n", ListLength(list));listNode(list);return 0;
}