每日一句
Life is but a dream.
人生如梦
**
内容概要
**
一、线性表(一对一)
1、顺序表:数组
2、链表
1)单链表
2)双链表
3)内核链表
3、栈
4、队列
二、非线性表(一对多,多对多)
1、二叉树
2、二叉搜索树(BST)
3、平衡二叉搜索树(AVL)
4、红黑树
C语言中数据结构所要研究的内容:
(1)逻辑结构
线性:顺序表,链表,栈,队列
非线性:树,图
(2)存储结构
顺序存储:将数据存储在一块连续的空间
链式存储:将数据存储在不连续的空间
(3)数据算法
增、删、改、查、排序、查找、旋转等等
一句话描述:用不同的方法(顺序表,链表,栈,队列,树)来管理和存储数据
这些内容我都会后续更新,先来看下前面的内容。
—————————————————————————分隔线————————————————
1.线性表优缺点
线性表是指在一堆数据中的任意一个节点,有且仅有一个前驱节点(除第一个节点以外),并有且仅有一个后继节点(除最后一个节点以外),就是“一对一”的关系。
1、顺序表:顺序存储的线性表
优点:
(1)空间利用率高
(2)查找效率高,可通过下标直接查找
缺点:
(1)需要一大块连续的空间
(2)插入和删除效率较低,因为需要移动成片的数据
(3)无法扩展长度,使用时必须预先知道长度
2.链表优缺点
链表:链式存储的线性表
优点:
(1)插入和删除效率高,保留原有的物理顺序,只需要改变指针指向即可
(2)没有内存空间限制
(3)可任意扩展长度
缺点:
(1)占用额外空间存放指针(浪费空间)
(2)查找效率比较低,要依次遍历节
顺序表也就是数组想必大家都清楚不过了,所以我就来分享一下链表的一些操作
对链表的操作:
·设计节点
·初始化空链表(创建单链表)
·插入节点
·删除节点
·移动节点
·查找节点
·遍历节点
这一节我就分享一下有关于单链表的操作:
第一步:设计节点,说明链表中存储的是什么数据
typedef struct node
{
int data; //数据域
struct node *next; //指针域
}node,*sigle_list;
node 相当于 struct node
sigle_list相当于struct node *
第二步:初始化空链表(创建一个链表)
sigle_list init_list(void)
{
sigle_list head = malloc(sizeof(node));
if(head != NULL)
{
head->next = NULL;
}
return head;
}
第三步:创建节点
sigle_list new_node(int data)
{
sigle_list new = malloc(sizeof(node));
if(new != NULL)
{
new->data = data;
new->next = NULL;
}
return new;
}
链表操作
第四步:链表操作
1.插入节点
图示:
从图中可以看到,图中是从链表的开头插入的。
void insert_node(sigle_list p,sigle_list new)
{
if(p == NULL || new == NULL)
return;
//插入链表
new->next = p->next; //第①步
p->next = new; //第②步
}
插入到尾部也类似,这里直接上代码
void insert_node_tail(sigle_list p,sigle_list new)
{
if(p == NULL || new == NULL)
return;
sigle_list tmp = p;
while(tmp->next != NULL) //找到最后一个节点
tmp = tmp->next;
tmp->next = new;
new->next = NULL;
}
2.删除节点
图示:
图中说明见代码
void remove_node(sigle_list head,sigle_list delete)
{
//判断链表是否为空
if(empty_list(head))
return;
//找到要删除的节点的前面一个节点 //第①步
sigle_list tmp = head;
while(tmp->next != delete)
{
tmp = tmp->next;
}
tmp->next = delete->next; //第②步
delete->next = NULL; //第③步
}
3.移动节点
可以看到图中移动节点,将节点p移动到anchor的后面
void move_node(sigle_list head,sigle_list p,sigle_list anchor)
{
remove_node(head,p); //先将p删除
insert_node(anchor,p); //再将p插在anchor的后面
}
4.查找节点
查找节点无非就是遍历每一个节点,如果找到就返回该节点位置,如果没有找到就返回空。
sigle_list find_node(sigle_list head,int data)
{
sigle_list tmp = head->next;
//判断链表是否为空
if(empty_list(head))
return NULL;
while(tmp != NULL)
{
if(tmp->data == data)
return tmp;
tmp = tmp->next;
}
return NULL;
}
5.遍历节点
跟查找类似,不过我将每个节点的数据都打印出来了
void show_list(sigle_list head)
{
//判断链表是否为空
if(empty_list(head))
return;
sigle_list tmp = head->next;
int i = 0;
for(;tmp != NULL;tmp = tmp->next)
{
if(i == 0)
printf("%d",tmp->data);
else
printf("->%d",tmp->data);
i++;
}
printf("\n");
}
好像单链表的操作大概就这些了,下一个博客我跟新一下循环链表的操作。
有什么问题欢迎留言。