/*
Author: panxiaolan
Time: 2021-10-09
单链表的基本操作(不带头节点):
(1).单链表的定义
(2).单链表的初始化
(3).单链表建立
a.头插法建立单链表
b.尾插法建立单链表
(4).单链表查找
a.按位查找
b.按值查找
(5).单链表的长度
(6).单链表插入
a.后插
b.前插
c.在某个位置插入
(7).单链表删除
a.删除指定位序上的元素
b.删除某个节点
(8).单链表的输出
*/
#include <stdio.h>
#include <stdlib.h>
// 单链表的定义
typedef struct LNode {
int data;
LNode *next;
} LNode,*ListLink;
// 单链表的初始化
void InitListLink(ListLink &L) {
L = NULL;
return ;
}
// 头插法建立单链表
ListLink Head_Create_ListLink(ListLink &L) {
InitListLink(L);
LNode *s;
int x;
while(scanf("%d",&x) != EOF) {
if(x == -1) break;
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
s->next = L; // 插入到头部
L = s; // 更新头部,这两步顺序不能乱
}
return L;
}
// 尾插法建立单链表
ListLink Tail_Create_ListLink(ListLink &L) {
InitListLink(L);
bool is_head = true;
int x;
LNode *s,*r = L;
while(scanf("%d",&x) != EOF) {
if(x == -1) break;
s = (LNode *)malloc(sizeof(LNode));
if(is_head) {
is_head = false;
s->data = x;
s->next = NULL;
L = s;
r = s;
}
// s 是新插入的节点
s->data = x;
// 此句可以省略,便于理解此处不再省略
s->next = NULL;
// 将新节点插入到尾队列中
r->next = s;
// r 重新指向尾部
r = s;
}
r->next = NULL;
return L;
}
// 按位查找,返回第 i 个节点(不带头节点)
LNode* getElem(ListLink &L,int i) {
if(i < 1) return NULL;
LNode *p = L;
int j = 1;
while(p && j < i) {
p = p->next;
j ++;
}
return p;
}
// 按值查找,找到数据域是 e 的节点
LNode* locateElem(ListLink &L,int e) {
LNode *p;
p = L;
while(p && p->data != e) {
p = p->next;
}
return p;
}
// 获取单链表的长度
int length(ListLink &L) {
int len = 0;
LNode *p = L;
while(p) {
len ++;
p = p->next;
}
return len;
}
// 后插操作: 在节点 P 之后插入元素 e
bool InsertNextNode(LNode *p,int e) {
if(!p) return false;
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
if(!s) return false;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
// 插入操作,在第 i 个位置插入元素 e
bool InsertNode(ListLink &L,int i,int e) {
LNode *p;
p = getElem(L,i - 1);
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
s->data = e;
// 后插操作
s->next = p->next;
p->next = s;
return true;
}
// 前插操作:在 p 节点前插入元素 e
bool InsertBeforeNode(LNode *p,int e) {
if(!p) return false;
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
if(!s) return false;
// s 现在的位置就是之前 p 的位置
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = e;
return true;
}
// 前插操作: 在 P 节点前插入节点 s
bool InsertNodeS(LNode *p,LNode *s) {
if(!p || !s) return false;
s->next = p->next;
p->next = s;
// 交换两个节点的数据域
int temp = s->data;
s->data = p->data;
p->data = temp;
return true;
}
// 删除操作: 删除 位序 i 的节点, e 是 i 节点的值
bool DeletePositionNode(ListLink &L,int i,int &e) {
if(i < 1) return false;
if(i > 1) {
LNode *p;
p = getElem(L,i - 1);
LNode *q = p->next;
e = q->data;
p->next = q->next;
free(q);
} else {
// i = 1 是头节点
if(L->next == NULL) {
e = L->data;
L = NULL;
} else {
e = L->data;
L = L->next;
}
}
return true;
}
// 删除操作 : 删除某个节点
bool DeleteNode(LNode *p) {
if(p->next == NULL) return false;
LNode *q;
q = p->next;
p->data = q->data;
p->next = q->next;
return true;
}
// 单链表的输出
void print(ListLink &L) {
LNode *s = L;
while(s != NULL) {
printf("%d ",s->data);
s = s->next;
}
printf("\n");
return ;
}
int main() {
ListLink L;
// 头插法建立单链表
printf("-------------头插法建立单链表--------------\n");
// Head_Create_ListLink(L);
// 尾插法建立单链表
printf("-------------尾插法建立单链表--------------\n");
Tail_Create_ListLink(L);
printf("-------------输出节点--------------\n");
// 输出节点
print(L);
printf("-------------按位序查找元素--------------\n");
LNode *p = getElem(L,2);
printf("%d \n",p->data);
printf("-------------按值查找元素--------------\n");
LNode *q = locateElem(L,3);
printf("%d \n",q->data);
printf("-------------单链表的长度--------------\n");
int len = length(L);
printf("%d \n",len);
printf("-------------后插操作: 在节点 P 之后插入元素 e--------------\n");
printf("在第 3 个元素后插入元素 e \n");
LNode *after;
after = getElem(L,3);
InsertNextNode(after,100);
printf("插入后的单链表\n");
print(L);
printf("-------------插入操作,在第 i 个位置插入元素 e--------------\n");
InsertNode(L,2,1001);
printf("在第 2 个位置插入1001操作完成后的单链表:\n");
print(L);
printf("-------------前插操作:在 p 节点前插入元素 e--------------\n");
LNode *before;
before = getElem(L,4);
InsertBeforeNode(before,99999);
printf("在第 4 个位置前插操作完成后的单链表:\n");
print(L);
printf("-------------前插操作: 在 P 节点前插入节点 s--------------\n");
LNode *first;
first = (LNode *)malloc(sizeof(LNode));
first->data = 12345678;
InsertNodeS(before,first);
printf("插入 first 节点后的序列:\n");
print(L);
printf("------------- 删除操作: 删除 位序 i 的节点, e 是 i 节点的值--------------\n");
int e;
printf("未删除元素的单链表:\n");
print(L);
DeletePositionNode(L,3,e);
printf("删除后的单链表是:\n");
print(L);
printf("删除元素的值是: %d \n",e);
printf("------------- 删除操作 : 删除某个节点--------------\n");
LNode *deleteDot;
deleteDot = getElem(L,1);
printf("未删除元素的单链表:\n");
print(L);
DeleteNode(deleteDot);
printf("删除后的单链表是:\n");
print(L);
return 0;
}
考研数据结构:(二)单链表(不带头节点)的基本操作(只有干货)
最新推荐文章于 2023-10-12 16:11:40 发布