数组与链表区别
数组:从栈空间中申请一些连续的字节数,使用变量间接访问这片内存空间,在定义时必须声明空间的大小。
例子: int A[5] -> 连续申请20个字节
A[0] A[1] ->使用变量间接访问这片内存空间
5 -> 必须声明空间的大小
链表:可以利用堆空间一些零碎空间,这些空间不需要连续的,使用内存上地址联系在一起的,不需要声明空间的大小!
原理:每一个内存中除了存放内存空间中本身有的数据,还存放着下一个内存空间的地址。
数组与链表如何访问下一个成员?
数组中每一个成员的类型一致并且地址是连续,肯定通过指针运算找到下一个元素
A[0] = *(A+0)
A[1] = *(A+1)
链表通过自身存储下一个成员的地址,访问下片内存的起始地址。
链表种类
- 传统链表
单向链表 节点1->节点2->节点3->NULL
双向链表 NULL<-节点1<->节点2<->节点3<->NULL
单向循环链表 节点1->节点2->节点3->节点1
双向循环链表 节点3<->节点1<->节点2<->节点3<->节点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;
}