C/C++ 笔记
QQ : 1841545843
邮箱 : jiaxx903@163.com
- 通过组合使用结构和指针创建强大的数据结构
- 单链表有一个根节点 root pointer
- 节点的声明
typedef struct NODE
{
struct NODE* link;
int value;
} Node;
- 单链表
// 单链表
typedef struct NODE
{
struct NODE* link;
int value;
} Node;
// 单链表的插入,遍历到插入位置然后始终保存一个指向链表当前节点之前的那个节点的指针
// 插入到一个有序链表中
#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h"
#defien FALSE 0
#define TRUE 1
int sll_insert(Node* current, int new_value)
{
Node* previous;
Node* new;
// 寻找正确的插入位置, 在current previous 之间
while (current->value < new->value)
{
previous = current;
current = current->link;
}
// 为新节点分配内存,并把新值存储到新节点中
new = (Node*)malloc(sizeof(Node));
if (new == NULL)
return FALSE;
new->value = new_value;
// 把新节点插入到链表中
new->link = current;
previous->link = new;
return TRUE;
}
- 上述函数的头和尾不能插入节点, 所以我们进行优化
// 在尾部对current的值进行测试,保证在执行current->value 之前不是一个NULL
while (current != NULL && current->value < value);
// 把一个指向root的指针作为参数传递给函数
// 参数的类型是 Node**
// 插入到一个有序链表中,函数的参数是一个指向链表根指针的指针,以及一个需要插入的值
#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h"
#define FALSE 0
#define TRUE 1
int sll_insert(Node** rootp, int new_value)
{
Node* current;
Node* prevoius;
Node* new;
// 得到指向第一个根节点的指针
current= *rootp;
previous = NULL;
// 寻找正确的插入位置
while (current != NULL && current->value < new_value)
{
previous = current;
current = current->link;
}
// 为新节点分配内存,并把新值存储到新节点中
new = (Node*)malloc(sizeof(Node));
if (new == NULL)
return FALSE;
new->link = current;
if (previous == NULL)
*rootp = new;
else
previous->link = new;
return TRUE;
}
// 调用
result = sll_insert(&root, 12);
- 插入的通性是我们拥有一个指向当前节点的指针,以及一个指向当前节点的link字段。
- 在看上去不同的操作中总结出共性。
- C语言提供了正确的工具,能够获取现存对象地址这一能力。
// 简化插入操作
// rootp 指向节点内的link字段, 取得当前节点的link字段地址,
¤t->link;
current = *linkp;
while (current != NULL && current->value < value )
{
linkp = ¤t->link;
current = *linkp;
}
- 双向链表
// 双链表声明
typedef struct NODE
{
struct NODE* fwd;
struct NODE* bwd;
int value;
} Node;
插入有四种情况
- 新值插入到链表的中间位置
- 新值插入到链表的起始位置
- 新值插入到链表的结束位置
- 新值插入到链表的起始位置与结束位置(原链表为空)
// 双链表声明
typedef struct NODE
{
struct NODE* fwd;
struct NODE* bwd;
int value;
} Node;
// 把一个值插入到双向链表中
// rootp 是一个指向根节点的指针
// 返回值,如果欲插入的值在链表中,返回0
// 插入失败返回 -1, 插入成功返回 1
#include <stdlib.h>
#include <stdio.h>
#include "double_NODE.h"
int dll_inbsert(Node* rootp, int value)
{
Node* this;
Node* next;
Node* newnode;
// 查看value是否已存在链表中
// this指向在新节点之前的那个节点
// next指向在新节点之后的那个节点
for (this == rootp; (next = this->fwd) != NULL; this = next)
{
if (next->vlue == value)
return 0;
if (next->value > value)
break;
}
newnode = (Node*)malloc(sizeof(Node));
if (newnode == NULL)
return -1;
newnode->value = value;
// 把新值添加到链表中
if (next != NULL)
{
// 并非位于链表尾部
if (this != rootp) // 并非位于链表的起始位置
{
newnode->fwd = next;
this->fwd = newnode;
newnode->bwd = this;
next->bwd = newnode;
}
else // 位于链表起始位置
{
newnode->fwd = next;
rootp->fwd = newnode;
newnode->bwd = NULL;
next->bwd = newnode;
}
// 位于链表尾部
else
{
if (this != rootp) // 并非位于链表的起始位置
{
newnode->fwd = NULL;
this->fwd = newnode;
newnode->bwd = this;
rootp->bwd = newnode;
}
else // 位于链表起始位置
{
newnode->fwd = NULL;
rootp->fwd = newnode;
newnode->bwd = NULL;
rootp->bwd = newnode;
}
}
return 1;
}
}