#include <stdio.h>
#include <stdlib.h>
#define OK 0
#define ERROR -1
typedef int ElemType;
// 线性表的链式存储结构(单链表)
typedef struct LNode {
// 数据域
ElemType data;
// 指针域
LNode *next;
} *LinkList;
// 头插法创建单链表
int create1(LinkList &L, int n);
// 尾插法创建单链表
int create2(LinkList &L, int n);
// 求单链表长度
int length(LinkList &L);
// 取元素
int get(LinkList &L, int i);
// 插入结点
int insert(LinkList &L, int i, ElemType e);
// 删除结点,返回删除元素
ElemType remove(LinkList &L, int i);
// 遍历链表
int display(LinkList &L);
// 销毁链表
int destroy(LinkList &L);
// 清空链表
int clear(LinkList &L);
// 逆置链表
void reverse_list(LNode *p, LinkList &L);
// 判断链表是否为空
int isNull(LinkList &L);
// 判断链表是否为空链表
int isEmpty(LinkList &L);
// 头插法,从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素
int create1(LinkList &L, int n) {
L = (LinkList) malloc(sizeof(LNode));// 建立带头结点的的单链表L
L->next = NULL;// 初始为空链表
// p为新结点,指向最后一个元素
LNode *p;
for (int i = 1; i <= n; i++) {
// 生成新结点
p = (LinkList) malloc(sizeof(LNode));
p->data = i;
p->next = L->next;
L->next = p;
}
return OK;
}
// 尾插法,从表头到表尾正向建立单链表L,每次均在表尾插入元素
int create2(LinkList &L, int n) {
L = (LinkList) malloc(sizeof(LNode));// 创建头结点
L->next = NULL;
LNode *p, *q = L;
for (int i = 1; i <= n; i++) {
// 生成新结点
p = (LinkList) malloc(sizeof(LinkList));
p->data = i;
p->next = NULL;// 不写报错
q->next = p;// 将头节点和新和新创建的结点链接起来
q = p;// q指向新的表尾结点(指针右移)
// or q = q->next;// q指向新的表尾结点
}
return OK;
}
ElemType get(LinkList &L, int i) {
// p指向L的首结点
LNode *p = L->next;
int j = 0;
// 顺指针向后查找,直到p为空(说明p已指向最后一个结点了)或p指向第i个元素
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j > i) {
return ERROR;
}
return p->data;
}
int insert(LinkList &L, int i, ElemType e) {
LNode *temp = L;// 创建临时结点,用于寻找第i-1个结点
int j;
// 首先找到插入位置的上一个结点,即temp指向的结点
for (j = 0; temp && j < i; j++) {
temp = temp->next;
}
if (!temp || j > i) {
return ERROR;
}
LNode *p = (LinkList) malloc(sizeof(LinkList));// 生成新结点(待插入的结点)
p->data = e;// 给新结点的数据域赋值
p->next = temp->next;// 将新结点的next指针指向插入位置后的结点
temp->next = p;// 将插入位置前的结点的next指针指向插入结点
return OK;
}
ElemType remove(LinkList &L, int i) {
LNode *temp = L;
int j;
// 寻找第i个结点,temp指向其前趋
for (j = 0; temp && j < i; j++) {
temp = temp->next;
}
if (!temp->next || j > i) {
return ERROR;
}
LNode *del = temp->next;// 单独设置一个指针指向被删除结点,以防丢失
ElemType e = del->data;// 存储待删除结点的数据,作为返回值
temp->next = del->next;// 删除某个结点的方法就是更改前一个结点的指针域
free(del);// 手动释放该结点,防止内存泄漏
return e;
}
int length(LinkList &L) {
// 判断链表是否为空
if (isNull(L)) {
return ERROR;
}
LNode *p = L->next;
int len = 0;
while (p != NULL) {
len++;
p = p->next;
}
return len;
}
int display(LinkList &L) {
// 判断链表是否为空
if (isNull(L)) {
return ERROR;
}
// 判断链表是否为空链表
if (isEmpty(L)) {
return ERROR;
}
// p指向首结点
LNode *p = L->next;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return OK;
}
int destroy(LinkList &L) {
LNode *temp;
while (L) {
temp = L->next;
free(L);
L = temp;
}
return OK;
}
int clear(LinkList &L) {
LNode *temp = L->next, *p;
while (temp) {
p = temp->next;
free(temp);
temp = p;
}
L->next = NULL;
}
void reverse_list(LNode *p, LinkList &L) {
if (p->next == NULL) {// 以p为首结点指针的单链表只有一个结点时
L->next = p; // p结点变为尾结点
return;
}
reverse_list(p->next, L);
p->next->next = p; // 将结点链接在尾结点之后
p->next = NULL; // 尾结点next域置为NULL
}
int isNull(LinkList &L) {
// 不存在头节点,链表不存在(未创建或已被销毁)
if (!L) {
printf("linklist is null!\n");
return ERROR;
}
return OK;
}
int isEmpty(LinkList &L) {
// 不存在首元节点,是空链表
if (!L->next) {
printf("linklist is empty!\n");
return ERROR;
}
return OK;
}
int main() {
LinkList linkList;
create2(linkList, 5);
display(linkList);
// 插入元素
insert(linkList, 5, 666);
display(linkList);
printf("length:%d\n", length(linkList));
printf("%d\n", get(linkList, 4));
printf("%d\n", remove(linkList, 5));
display(linkList);
reverse_list(linkList->next, linkList);
display(linkList);
clear(linkList);
display(linkList);
printf("length:%d\n", length(linkList));
destroy(linkList);
printf("length:%d\n", length(linkList));
//display(linkList);
return 0;
}
运行结果