初步学习数据结构时,课通过C语言实现单链表的基本操作。如头插法与尾插法建立链表,链表的初始化、插入、删除与查找等。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define headnote
//typedef struct LNode LNode;
/*定义一个单链表*/
typedef struct LNode { //定义单链表结点类型
int data; //每个节点存放一个数据元素
struct LNode* next; //指针指向下一个节点
}LNode,*LinkList;
/*初始化单链表*/
bool InitList(LinkList *L) {
#ifndef headnote
L = NULL; //空表,暂时还没有任何节点
#else
(* L) = (LNode*)malloc(sizeof(LNode));//分配一个头结点
if (L == NULL) //内存不足,分配失败
return false;
(*L)->next = NULL; //头结点后暂时还没有结点
#endif // !headnote
return true;
}
/*判断单链表是否为空*/
bool Empty(LinkList L) {
#ifndef headnote
return (L == NULL);
#else
return (L->next == NULL);
#endif // !headnote
}
/*按位查找*/
LNode* GetElem(LinkList* L, int i) {
if (i < 1)
return NULL;
LNode* p; //指针p指向当前扫描到的结点
int j = 0; //当前p指向的是第几个结点
p = (*L); //L指向头结点,头结点是第0个结点(不存数据
while (p != NULL && j < i) { //循环找到第i个结点
p = p->next;
j++;
}
return p;
}
/*按值查找*/
int LocateElem(LinkList* L, int i) {
LNode* p=(*L)->next; //从第1个结点开始查找数据域为e的结点
int j = 1;
while (p != NULL && p->data!=i) {
p = p->next;
j++;
}
return j;
}
/*求表长*/
int Length(LinkList* L) {
int len = 0;
LNode* p = (*L);
while (p->next != NULL) {
p = p->next;
len++;
}
return len;
}
/*指定节点的后插操作*/
bool InsertNextNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL)
return false;
s->data = e; //用结点s保存数据元素s
s->next = p->next;
p->next = s; //将结点s连到p之后
return true;
}
/*指定结点的前插操作*/
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL)
return false;
s->next = p->next;
p->next = s; //新结点s连到p之后
s->data = p->data; //将p中元素复制到s中
p->data = e; //p中元素覆盖为e
return true;
}
/*指定结点的删除*/
bool DeleteNote(LNode* p) {
if (p == NULL)
return false;
LNode* q = p->next; //令q指向*p的后继节点
p->data = p->next->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中断开
free(q); //释放后继结点的存储空间
return true;
}
/*按位序插入*/
bool ListInsert(LinkList *L, int i, int e) {
if (i < 1)
return false;
#ifndef headnote
if (i == 1) { //插入第1个结点的操作与其他结点操作不同
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = (*L);
(*L) = s; //头指针指向新结点
return true;
}
#endif // !headnote
LNode* p; //指针p指向当前扫描到的结点
int j = 0; //当前p指向的是第几个结点
p = (*L); //L指向头结点,头结点是第0结点(不存数据)
while (p != NULL && j < i - 1) {//循环找到第i-1个结点
p = p->next;
j++;
}
InsertNextNode(p, e);
return true;
}
/*按位序删除*/
bool ListDelete(LinkList *L, int i, int* e) {
if (i < 1)
return false;
LNode* p;
int j = 0;
p = (*L);
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL)
return false;
if (p->next == NULL) //第i-1个结点之后已无其他结点
return false;
LNode* q = p->next; //令q指向被删除结点
*e = q->data; //用e返回元素的值
p->next = q->next; //将*q结点从链中断开
free(q); //释放结点的存储空间
return true; //删除成功
}
/*尾插法建立单链表*/
LinkList List_TailInsert(LinkList* L) { //正向建立单链表
int x; //设ElemType为整型
(*L) = (LinkList)malloc(sizeof(LNode)); //建立头结点
LNode* s, * r = (*L); //r为表尾指针
scanf_s("%d", &x); //输入结点的值
while (x != 9999) { //输入9999表示结束
s= (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s; //r指向新的表尾结点
scanf_s("%d", &x);
}
r->next = NULL; //尾结点指针为空
return (*L);
}
/*头插法建立单链表*/
LinkList List_HeadInsert(LinkList* L) { //逆向建立单链表
LNode* s;
int x;
(*L) = (LinkList)malloc(sizeof(LNode)); //建立头结点
(*L)->next = NULL; //初始为空表
scanf_s("%d", &x);
while (x != 9999) {
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = (*L)->next;
(*L)->next = s;
scanf_s("%d", &x);
}
return (*L);
}
void main() {
LinkList L; //声明一个指向单链表的指针
InitList(&L); //初始化一个空表
ListInsert(&L,1,11); //11
InsertNextNode(L->next, 13);//11,13
InsertPriorNode(L->next->next, 12);//11,12,13
printf("此时该单链表的表长为%d\n", Length(&L));
int i = 2;
printf("第%d位数据为%d\n", i, (GetElem(&L,i))->data);
i = 12;
printf("数据为%d的结点在第%d位\n", i, LocateElem(&L, i));
int e = -1;
ListDelete(&L, 2, &e);//11,13
DeleteNote(L->next);//13
}
过程中遇到的问题:
"->next"的左侧必须指向结构/联合
解决办法:
->操作符优先级高于*操作符优先级,把L->next换成(*L)->next即可
'scanf':this function or variable may be unsafe.Consider using scanf_s instead
解决方法:
将scanf替换为提示中的scanf_s
1667

被折叠的 条评论
为什么被折叠?



