我初识链表

数组与链表区别

数组:从栈空间中申请一些连续的字节数,使用变量间接访问这片内存空间,在定义时必须声明空间的大小。

例子: int A[5] -> 连续申请20个字节
A[0] A[1] ->使用变量间接访问这片内存空间
5 -> 必须声明空间的大小

链表:可以利用堆空间一些零碎空间,这些空间不需要连续的,使用内存上地址联系在一起的,不需要声明空间的大小!
原理:每一个内存中除了存放内存空间中本身有的数据,还存放着下一个内存空间的地址。

数组与链表如何访问下一个成员?

数组中每一个成员的类型一致并且地址是连续,肯定通过指针运算找到下一个元素
A[0] = *(A+0)
A[1] = *(A+1)

链表通过自身存储下一个成员的地址,访问下片内存的起始地址。

链表种类
  1. 传统链表
    单向链表 节点1->节点2->节点3->NULL
    双向链表 NULL<-节点1<->节点2<->节点3<->NULL

单向循环链表 节点1->节点2->节点3->节点1
双向循环链表 节点3<->节点1<->节点2<->节点3<->节点1

  1. 内核链表
    调用内核中头文件宏定义,实现链表各种尾插,头插…
链接每一个节点模型

struct list_node{
/* 数据域 */
int a;

/* 指针域 */
struct list_node *next;
};

注意:
1)头节点有没有效 -> 头节点数据域存不存放数据。
2)一般地,循环链表都是头节点无效,非循环链表头节点可以有效/无效
3)每一个链表学习创建链?尾插入节点?头插?检索链表?寻找特征值?删除节点?释放节点的内存空间。

写单向链表代码
1. 设计链表中每一个节点模型
struct list_node{
	int a;
	struct list_node *next;
};

2. 初始化链表头
struct list_node *init_list_head(struct list_node *head) //head=NULL
{
	//1. 为头节点申请内存空间
	head = (struct list_node *)malloc(sizeof(struct list_node));
	
	//2. 为头节点的数据域与指针域
	head->a = 10;
	head->next=NULL;
	
	return head;
}

3. 尾插一个数据到链表的末尾

int add_list_tail(struct list_node*head,int num)
{
	if(head == NULL)
		return -1;
	
	//1. 为尾插的节点申请空间
	struct list_node *Node = NULL;
	Node = (struct list_node *)malloc(sizeof(struct list_node));
	if(Node == NULL)
	{
		printf("malloc error!\n");
		return -1;
	}
	
	//2. 为尾插的节点赋值
	Node->a = num;
	Node->next = NULL;
	
	struct list_node *p = NULL;
	for(p=head;p->next!=NULL; p=p->next); //从循环中跳出来时,p一定是指向最后一个节点!
	
	p->next = Node;
	
	return 0;
}

4. 头插

int add_list_head(struct list_node*head,int num)
{
	if(head == NULL)
		return -1;
	
	//1. 为尾插的节点申请空间
	struct list_node *Node = NULL;
	Node = (struct list_node *)malloc(sizeof(struct list_node));
	if(Node == NULL)
	{
		printf("malloc error!\n");
		return -1;
	}
	
	//2. 为新节点赋值
	Node->a = num;
	Node->next = head->next;
	head->next = Node;
	
	return 0;
}

5. 遍历链表
int show_list_node(struct list_node *head)
{
	if(head == NULL)
		return -1;
	
	struct list_node*p = NULL;
	for(p=head;p!=NULL;p=p->next)
	{
		printf("node data:%d\n",p->a);
	}
	
	return 0;
}

6. 根据特征值寻找节点
int show_node(struct list_node *p)
{
	if(p == NULL)
		return -1;
	
	printf("p->a:%d\n",p->a);
	return 0;
}

int search_list_node(struct list_node *head,int search_num)
{
	if(head == NULL)
		return -1;
	
	struct list_node*p = NULL;
	for(p=head;p!=NULL;p=p->next)
	{
		if(p->a == search_num)
		{
			show_node(p);
			return 0;
		}	
	}
	
	printf("not found this node!\n");
	return -2;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值