《C和指针》笔记(九)-- 使用结构和指针

C/C++ 笔记

QQ : 1841545843
邮箱 : jiaxx903@163.com

  1. 通过组合使用结构和指针创建强大的数据结构
  2. 单链表有一个根节点 root pointer
  3. 节点的声明
typedef struct NODE
{
	struct NODE* link;
	int value;
} Node;
  1. 单链表
// 单链表
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字段地址,
&current->link;

current = *linkp;
while (current != NULL && current->value < value )
{
	linkp = &current->link;
	current = *linkp;
}
  1. 双向链表

// 双链表声明
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;
		
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值