图解数据结构
文章目录
前言
计算机两条腿:数学和英语
学好数据结构,爸爸妈妈直夸你好孩子!!!
一、单链表是什么?
单链表是一种链式存取的数据结构,链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。以“结点的序列”表示的线性表称作线性链表(单链表),单链表是链式存取的结构。
对于链表的每一个结点,我们使用结构体(struct)进行设计,其主要内容有:
二、单链表基本操作
1.结构体创建
代码如下(示例):
typedef struct Node{
int data;
struct Node *next;
} Node;
typedef Node *LinkList ; // 方便获取地址
2.头插法建表
代码如下(示例):
LinkList CreateListHead(LinkList L, int n){ // 头插法
LinkList p;
L = (LinkList)malloc(sizeof(Node)); // 定义头节点
L->next = NULL;
printf("p--value=");
for (int i=0; i<n; i++){
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100 + 1; // 随机数1-100
p->next = L->next; // 重点记忆
L->next = p; // 重点记忆
printf("%d ", p->data);
}
printf("\n");
return L;
}
看不懂?看个图吧(你真是个小蠢猪)
3.尾插法建表
代码如下(示例):
LinkList CreateListTail(LinkList L, int n){ // 尾插法
LinkList p, r;
L = (LinkList)malloc(sizeof(Node));
r = L;// 定义尾部节点;
printf("p--value=");
for(int i=0; i<n; i++){
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100 + 1;
r->next = p;
r = p; // 相当于指针下移到了P,在下一次循环时候把上一个p的next赋值当前循环中的p;
printf("%d ", p->data);
}
printf("\n");
r->next = NULL;
return L;
}
还看不懂?看个图吧(你真是个小笨蛋)
4.添加节点
LinkList SetElem(LinkList L, int value){
LinkList p, s;
p = L; // 初始化;
s = (LinkList)malloc(sizeof(Node));
s->data = value;
s->next = p->next;
return s;
}
还看不懂?看个图吧(你真是个猪)
5.插入节点
void ListInsert(LinkList L, int i, int value){ // 插入节点
int num = 1; // 计数开始;
LinkList p, s;
p = L; // 初始化链表
while(p && num<i){ // 相当于寻找i节点当num=i时说明找到了
p = p->next;
++num;
}
if (i>num){
printf("insert-fill-error");
} else{
s = (LinkList)malloc(sizeof(Node));
s->data = value;
s->next = p->next; //相当于我把p记录的下一个节点的地址给了s
p->next = s; // 把p的next记录为s的地址;
printf("insert-OK");
}
}
还看不懂?看个图吧(你真是个笨蛋)
6.删除节点
void ListDelect(LinkList L, int i){ // 删除表中某个数据
int num = 1; // 计数开始
LinkList p, q;
p = L;
while (p->next && num<i){
p = p->next;
++num;
}
if(!(p->next) || num > i){
printf("Delect--no found--error!");
} else{
q = p->next;
p->next = q->next;
printf("Delect--ok!");
}
}
看图!!!
7.查找节点
void GetElem(LinkList L, int i){ // 查找元素
int num = 1;
LinkList p;
p = L->next;
while(p && num<i){
p = p->next;
++num;
}
if(i > num){
printf("GetElem--fill--error\n");
} else{
printf("The Elem value=%d\n", p->data);
}
}
8.清空表
void ListClear(LinkList L){ // 清空表
LinkList p,q;
p = L->next;
while (p){
q = p->next;
free(p);
p = q;
}
L->next = NULL;
printf("Clear--OK\n");
}
三、循环单链表
什么叫做循环单链表呢?头尾相接的就是循环单链表
我们还是按照两种建表方式来创建循环单链表
1.结构体创建
typedef struct CNode{
int data;
struct CNode *next;
} CNode;
typedef CNode *LinkList;
2.头插法建表
LinkList CreateHeadList(LinkList L, int n){ // 头插法建立循环单链表;
LinkList p;
L = (LinkList)malloc(sizeof(CNode));
L->next = L;
L->data = -1;
for(int i=0; i<n; i++){
p = (LinkList)malloc(sizeof(CNode));
p->data = rand()%100 + 1;
p->next = L->next;
L->next = p;
}
return L;
}
3.尾插法建表
LinkList CreateTailList(LinkList L, int n){ // 尾插法创建循环单链表
LinkList p, r;
L = (LinkList)malloc(sizeof(CNode));
L->data = -1;
r = L;// 定义尾部节点;
for(int i=0; i<n; i++){
p = (LinkList)malloc(sizeof(CNode));
r->next = p;
p->data = rand()%100 + 1;
r = p;
}
r->next = L; // 此时r就是最后一个p故指针指向头指针即可;
return L;
}
4.插入操作
void InsertElem(LinkList L, int i, int value){ // 插入元素
LinkList p,s;
p = L;
int num = 1;
while (p && num < i){
p = p->next;
++num;
}
if(!p || num < i || i<1){
printf("insert-fill-error");
}else{
s = (LinkList)malloc(sizeof(CNode));
s->data = value;
s->next = p->next;
p->next = s;
printf("insert-OK");
}
}
5.删除操作
void DelectElem(LinkList L, int i){ // 删除元素
LinkList p, q;
int num = 1;
p = L;
while (p && num < i){
p = p->next;
++num;
}
if(!(p->next) || num > i){
printf("Delect--error--fill");
}else{
q = p->next;
p->next = q->next;
printf("Delect--OK");
}
}
总结
实在看不懂的话,问问自己数据结构是不是跟体育老师学的。还是学C语言的时候做梦去了!!!