PART1 基本概念
1.1 单链表是线性表的链式存储结构,它是指通过一组任意的存储单元来存储线性表的数据元素。
1.2 单链表=结点-结点-结点-结点-结点-结点-结点-结点-结点
结点=数据域(存储单个数据)+指针域(指向下一个结点的指针)
1.3 此数据结构的基本操作为增、删、查、改。
PART2 代码实现
以带头节点的单链表为例
2.1 单链表的结点的类型描述
typedef struct lnode {
int data; //数据域
struct lnode* next; //指针域
}lnode,*linklist;
2.2 单链表的建立-头插法/尾插法
2.2.1 头插法建立单链表 (此算法适用于链表的逆置)
linklist List_HeadInsert(linklist& l) {
lnode* s;
l = (linklist)malloc(sizeof(lnode));
l->next = NULL;
int m;
scanf("%d", &m);
while (m != 999) {
s = (linklist)malloc(sizeof(lnode));
s->data = m;
s->next = l->next;
l->next = s;
scanf("%d", &m);
}
return l;
}
2.2.2 尾插法建立单链表 (此算法正序建立单链表)
linklist List_TailInsert(linklist& l) {
l = (linklist)malloc(sizeof(lnode));
l->next = NULL;
lnode* s, * r = l;
int m;
scanf("%d", &m);
while (m != 999) {
s = (linklist)malloc(sizeof(lnode));
s->data = m;
r->next = s;
r = s;
scanf("%d", &m);
}
r->next = NULL;
return l;
}
2.3 按值/位查找
2.3.1 按值查找
lnode* LocateElem(linklist l, int x) {
lnode* p = l->next;
while (p != NULL && p->data != x) {
p = p->next;
}
return p;
}
2.3.2 按位查找
lnode* GetElem(linklist l, int i) {
if (i == 0) return l;
if (i < 1) return NULL;
int j = 1;
lnode* p = l->next;
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
2.4 插入结点
2.4.1 将值为x的结点插入到单链表的第i个位置上
linklist ListInsert(linklist &l, int i,int x) {
lnode* s,*p;
s = (lnode*)malloc(sizeof(lnode));
s->data = x;
p = GetElem(l, i - 1);
s->next = p->next;
p->next = s;
return l;
}
2.4.2 对某一结点进行前插操作(狸猫换太子)
linklist ListInsert1(linklist& l, int i, int x) {
lnode* s,*p;
s = (lnode*)malloc(sizeof(lnode));
s->data = x;
p = GetElem(l, i - 1);
s->next = p->next;
p->next = s;
int t =s->data;
s->data = p->data;
p->data = t;
return l;
}
2.5 删除结点
主要思想:先定位到删除的结点,新建结点指向删除结点之后,将后继结点值赋给要删除结点,改变要删除节点的指针,指向新建结点之后,释放新建结点。
linklist ListDelete(linklist& l, int i) {
lnode* p, * q;
p = GetElem(l,i);
q = p->next;
p->data = p->next->data;
p->next = q->next;
free(q);
return l;
}
2.6 完整版代码
#include <iostream>
using namespace std;
typedef struct lnode {
int data;
struct lnode* next;
}lnode,*linklist;
linklist List_HeadInsert(linklist& l) {
lnode* s;
l = (linklist)malloc(sizeof(lnode));
l->next = NULL;
int m;
scanf("%d", &m);
while (m != 999) {
s = (linklist)malloc(sizeof(lnode));
s->data = m;
s->next = l->next;
l->next = s;
scanf("%d", &m);
}
return l;
}
linklist List_TailInsert(linklist& l) {
l = (linklist)malloc(sizeof(lnode));
l->next = NULL;
lnode* s, * r = l;
int m;
scanf("%d", &m);
while (m != 999) {
s = (linklist)malloc(sizeof(lnode));
s->data = m;
r->next = s;
r = s;
scanf("%d", &m);
}
r->next = NULL;
return l;
}
lnode* LocateElem(linklist l, int x) {
lnode* p = l->next;
while (p != NULL && p->data != x) {
p = p->next;
}
return p;
}
lnode* GetElem(linklist l, int i) {
if (i == 0) return l;
if (i < 1) return NULL;
int j = 1;
lnode* p = l->next;
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
linklist ListInsert(linklist &l, int i,int x) {
lnode* s,*p;
s = (lnode*)malloc(sizeof(lnode));
s->data = x;
p = GetElem(l, i - 1);
s->next = p->next;
p->next = s;
return l;
}
linklist ListInsert1(linklist& l, int i, int x) {
lnode* s,*p;
s = (lnode*)malloc(sizeof(lnode));
s->data = x;
p = GetElem(l, i - 1);
s->next = p->next;
p->next = s;
int t =s->data;
s->data = p->data;
p->data = t;
return l;
}
linklist ListDelete(linklist& l, int i) {
lnode* p, * q;
p = GetElem(l,i);
q = p->next;
p->data = p->next->data;
p->next = q->next;
free(q);
return l;
}
void PrintList(linklist l) {
lnode* p = l->next;
for (int i = 1; p!=NULL; i++) {
cout << p->data<<" ";
p = p->next;
}
cout << endl;
}
int main() {
linklist l1, l2;
List_HeadInsert(l1);
PrintList(l1);
List_TailInsert(l2);
PrintList(l2);
ListInsert1(l2, 4, 5);
PrintList(l2);
ListDelete(l2, 3);
PrintList(l2);
return 0;
}