首先是单链表的定义,使用结构体定义两个部分,分别是数据域和指针域。
点击查看代码
typedef struct LNode{ElemType data;struct LNode *next;
}LNode, *LinkList;
这里可以使用typedef关键字将后续的定义简化。
具体例子如下:
- 如果这样定义struct LNode{}的话。在定义LNode类型变量的时候我们需要这样写,struct LNode L;
- 如果是使用typedef可以将struct省略掉。直接这样写:LNode L;
对链表的初始化(带头节点、不带头节点)
点击查看代码
// 无头节点初始化链表
bool InitListNoHead(LinkList &L){ return (L == NULL);
}// 有头节点的初始化链表
bool InitListWithHead(LinkList &L){L = (LNode *) malloc(sizeof(LNode));if(L == NULL) return 0;L->next = NULL;return 1;
}
单链表的插入(指定位置插入、节点前后插入)
点击查看代码
// 在链表中指定位置插入值
bool InsertElemPos(LinkList &L, int pos, int e){if(pos < 1) return 0;LNode *p = L;int j = 0;while(p != NULL && j < pos - 1){p = p->next;j ++;}if(p == NULL) return 0;LNode *t = (LNode*)malloc(sizeof(LNode));t->data = e;t->next = p->next;p->next = t;return 1;
}// 链表中指定节点后面插入(后插)
bool InsertNextNode(LNode *p, ElemType e){if(p == NULL) return 0;LNode *s = (LNode *)malloc(sizeof(LNode));if(s == NULL) return 0;s->data = e;s->next = p->next;p->next = s;return 1;
}// 链表中指定节点前面插入(前插)
// 注意前插操作要确定是不是第一个节点,是的话要特殊处理
bool InsertPriorNode(LNode *p, ElemType e){
// cout << (p->data) << endl;
// p = p->next;if(p == NULL) return 0;LNode *s = (LNode*)malloc(sizeof(LNode));if(s == NULL) return 0;s->next = p->next;s->data = p->data;p->data = e;p->next = s;return 1;
}
链表的删除操作
点击查看代码
// 删除第pos个节点并传回
bool DeleteNodePos(LinkList L, int pos, ElemType &e){if(pos < 1) return 0;LNode *p = L;int j = 0;while(p != NULL && j < pos - 1){p = p->next;j ++;}if(p == NULL || p->next == NULL) return 0;e = p->next->data;p->next = p->next->next;return 1;
}// 删除指定节点
// 如果要删除的是最后一个会出现无值可删的bug
bool DeleteNodeVal(LNode *p){if(p == NULL) return 0;p->data = p->next->data;p->next = p->next->next;return 1;
}
获取链表元素以及获取长度
点击查看代码
// 链表中获取第i个节点
LNode *GetElem(LinkList L, int i){if(i < 0) return NULL;LNode *p;int j = 0;p = L;while(p != NULL && j < i){p = p->next;j ++;}return p;
}// 链表中获取值为e的节点
LNode *LocateElem(LinkList L, ElemType e){LNode *p = L;while(p != NULL && p->data != e){p = p->next;}return p;
}// 获取链表长度
int GetLength(LinkList L){LNode *p = L;int len = 0;while(p->next != NULL){p = p->next;len ++;}return len;
}
链表头插、尾插实现初始化
点击查看代码
// 尾插节点
LinkList List_TailInsert(LinkList &L, int n){int x;L = (LinkList)malloc(sizeof(LNode));LNode *s, *p = L;for(int i = 1;i <= n;i ++){cin >> x;s = (LNode *)malloc(sizeof(LNode)); s->data = x;p->next = s;p = s;}p->next = NULL;return L;
}// 头插节点 (逆置链表操作)
LinkList List_HeadInsert(LinkList &L, int n){int x;L = (LinkList)malloc(sizeof(LNode));L->next = NULL; // 没这句话就是无头节点的链表 LNode *s, *p = L;for(int i = 1;i <= n;i ++){cin >> x;s = (LNode *)malloc(sizeof(LNode)); s->data = x;s->next = p->next;p->next = s; }return L;
}
output链表
void ListPrint(LNode *L){
LNode *p = L;
p = p->next;
while(p != NULL){
cout << p->data << ' ';
p = p->next;
cout << endl;
}
完整代码:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef int ElemType;
typedef struct LNode{ElemType data;struct LNode *next;
}LNode, *LinkList;// 无头节点初始化链表
bool InitListNoHead(LinkList &L){ return (L == NULL);
}// 有头节点的初始化链表
bool InitListWithHead(LinkList &L){L = (LNode *) malloc(sizeof(LNode));if(L == NULL) return 0;L->next = NULL;return 1;
}// 在链表中指定位置插入值
bool InsertElemPos(LinkList &L, int pos, int e){if(pos < 1) return 0;LNode *p = L;int j = 0;while(p != NULL && j < pos - 1){p = p->next;j ++;}if(p == NULL) return 0;LNode *t = (LNode*)malloc(sizeof(LNode));t->data = e;t->next = p->next;p->next = t;return 1;
}// 链表中指定节点后面插入(后插)
bool InsertNextNode(LNode *p, ElemType e){if(p == NULL) return 0;LNode *s = (LNode *)malloc(sizeof(LNode));if(s == NULL) return 0;s->data = e;s->next = p->next;p->next = s;return 1;
}// 链表中指定节点前面插入(前插)
bool InsertPriorNode(LNode *p, ElemType e){
// cout << (p->data) << endl;p = p->next;if(p == NULL) return 0;LNode *s = (LNode*)malloc(sizeof(LNode));if(s == NULL) return 0;s->next = p->next;s->data = p->data;p->data = e;p->next = s;return 1;
}// 删除第pos个节点并传回
bool DeleteNodePos(LinkList L, int pos, ElemType &e){if(pos < 1) return 0;LNode *p = L;int j = 0;while(p != NULL && j < pos - 1){p = p->next;j ++;}if(p == NULL || p->next == NULL) return 0;e = p->next->data;p->next = p->next->next;return 1;
}// 删除指定节点
bool DeleteNodeVal(LNode *p){if(p == NULL) return 0;p->data = p->next->data;p->next = p->next->next;return 1;
}// 链表中获取第i个节点
LNode *GetElem(LinkList L, int i){if(i < 0) return NULL;LNode *p;int j = 0;p = L;while(p != NULL && j < i){p = p->next;j ++;}return p;
}// 链表中获取值为e的节点
LNode *LocateElem(LinkList L, ElemType e){LNode *p = L;while(p != NULL && p->data != e){p = p->next;}return p;
}// 获取链表长度
int GetLength(LinkList L){LNode *p = L;int len = 0;while(p->next != NULL){p = p->next;len ++;}return len;
}// 尾插节点
LinkList List_TailInsert(LinkList &L, int n){int x;L = (LinkList)malloc(sizeof(LNode));LNode *s, *p = L;for(int i = 1;i <= n;i ++){cin >> x;s = (LNode *)malloc(sizeof(LNode)); s->data = x;p->next = s;p = s;}p->next = NULL;return L;
}// 头插节点 (逆置链表操作)
LinkList List_HeadInsert(LinkList &L, int n){int x;L = (LinkList)malloc(sizeof(LNode));L->next = NULL; // 没这句话就是无头节点的链表 LNode *s, *p = L;for(int i = 1;i <= n;i ++){cin >> x;s = (LNode *)malloc(sizeof(LNode)); s->data = x;s->next = p->next;p->next = s; }return L;
}// 打印链表
void ListPrint(LNode *L){LNode *p = L;p = p->next;while(p != NULL){cout << p->data << ' ';p = p->next;}cout << endl;
}
int main(){LinkList L;ElemType val;int n; cin >> n;List_HeadInsert(L, n);ListPrint(L);cout << "获取链表长度:\n"; int len = GetLength(L);cout << "len:" << len << endl;cout << "插入指定位置:\n"; InsertElemPos(L, 3, 3);ListPrint(L);cout << "插入指定节点的后面:\n"; InsertNextNode(L, 3); ListPrint(L);cout << "插入指定节点的前面:\n"; InsertPriorNode(L, 100); ListPrint(L);cout << "获取第i个节点:\n"; LNode *T = GetElem(L, 2);cout << (T->data) << endl;cout << "获取值为e的节点:\n"; T = LocateElem(L, 2);cout << (T->data) << endl; cout << "删除第3个节点:\n"; DeleteNodePos(L, 3, val);cout << val << endl;ListPrint(L);return 0;
}