数据结构基本概念:
1.定义
一组用来保存一种或者多种特定关系的数据的集合(组织和存储数据)
程序的设计:将现实中大量而复杂的问题以特定的数据类型和特定的存储结构存储在内存中,
并在此基础上实现某个特定的功能的操作;
程序 = 数据结构 + 算法
2.数据与数据之间的关系
数据的逻辑结构:
数据元素与元素之间的关系
集合 :关系平等
线性结构: 元素之间一对一的关系(表(数组,链表),队列。栈。。。)
树型结构: 元素之间一对多的关系(二叉树)
**图形结构:**元素之间多对多的关系(网状结构)
数据的物理结构:
数据的逻辑结构在计算机内存中的存储形式
**顺序存储:**采用一段连续的内存空间保存元素
优点: 空间连续,访问方便
缺点: 插入删除需要移动大量的元素
需要预分配内存空间
容易造成存储空间碎片
**链式存储:**采用一组非连续的内存空间保存元素
缺点: 访问元素效率低
优点 :插入和删除数据方便
不需要预分配内存
索引存储: 通过关键字构建索引表,通过索引表来来找到数据的存储位置
散列存储(哈希存储) :将数据元素的存储位置与关键码之间建立确定对
应关系从而实现查找的存储方式
指针,数组,数组指针,指针数组的区别:
1. 指针(Pointer)
指针是一个变量,它存储的是另一个变量的内存地址,而不是数据本身。通过指针,我们可以直接访问和操作内存中的数据。指针的声明通常使用星号(*)前缀,如 int *ptr;
表示 ptr
是一个指向整数的指针。
2. 数组(Array)
数组是一系列相同类型的数据项的集合,这些数据项在内存中连续存储。数组通过索引来访问其元素,索引从0开始。数组的声明方式如 int arr[10];
表示 arr
是一个包含10个整数的数组。
3. 数组指针(Pointer to an Array)
数组指针是指向整个数组的指针。这意味着,它存储的是数组首元素的地址,但与普通指针不同的是,通过它可以知道数组的大小(如果指针类型明确指定了数组的长度)。然而,在C语言中,直接声明一个"指向数组的指针"的语法并不直接支持指定数组的长度,但可以通过指针的运算或类型定义来间接实现。通常我们说的数组指针是指向数组第一个元素的指针,如 int (*ptr)[10];
声明了一个指向包含10个整数的数组的指针。
4. 指针数组(Array of Pointers)
指针数组是数组的每个元素都是指针的数组。这些指针可以指向相同类型的数据,也可以指向不同类型的数据(但在大多数情况下,为了类型安全,它们会指向相同类型的数据)。指针数组的声明方式如 int *ptrArray[5];
表示 ptrArray
是一个包含5个指向整数的指针的数组。
区别总结
- 指针:存储的是变量的内存地址,用于直接访问和操作内存中的数据。
- 数组:一系列相同类型的数据项的集合,通过索引访问。
- 数组指针:指向整个数组的指针,但C语言标准中不直接支持指定长度的数组指针,通常指向数组首元素的指针。
- 指针数组:数组的每个元素都是指针,这些指针可以指向相同或不同类型的数据。
有头链表:
创建链表:
Link_t *create_link()
{
Link_t *plink = (Link_t *)malloc(sizeof(Link_t));
if(NULL == plink)
{
perror("malloc fail");
return NULL;
}
plink->phead = NULL;
plink->clen = 0;
return plink;
}
头插
int push_link_head(Link_t *plink,DataType data)
{
Link_Node_t *pnode = (Link_Node_t *)malloc(sizeof(Link_Node_t));
if(NULL == pnode)
{
perror("malloc fail");
return -1;
}
pnode->data = data;
pnode->pnext = NULL;
pnode->pnext = plink->phead;
plink->phead = pnode;
plink->clen++;
return 0;
}
链表的遍历:
void print_link(Link_t *plink)
{
Link_Node_t *p = plink->phead;
while(p != NULL)
{
printf("%d ",p->data);
printf("%p ",p);
printf("\n");
p = p->pnext;
}
}
尾插
int is_empty_link(Link_t *plink)
{
return NULL == plink->phead;
}
int push_link_end(Link_t *plink,DataType data)
{
Link_Node_t *pnode = (Link_Node_t *)malloc(sizeof(Link_Node_t));
if(pnode == NULL)
{
perror("fail malloc");
return -1;
}
pnode->data = data;
pnode->pnext = NULL;
/*
if(plink->phead == NULL)
{
push_link_head(plink,data);
}*/
if(is_empty_link(plink))
{
plink->phead = pnode;
}
else
{
Link_Node_t *p = plink->phead;
while(p->pnext != NULL)
{
p = p->pnext;
}
p->pnext = pnode;
}
plink->clen++;
return 0;
}
头删
int pop_link_head(Link_t *plink)
{
if(is_empty_link(plink))
{
return 0;
}
Link_Node_t *p = plink->phead;
plink->phead = p->pnext;
free(p);
plink->clen--;
return 0;
}
尾删
int pop_link_end(Link_t *plink)
{
if(is_empty_link(plink))
{
return 0;
}
Link_Node_t *p = plink->phead;
if(NULL == p->pnext)
{
pop_link_head(plink);
}
while(p->pnext->pnext != NULL)
{
p = p->pnext;
}
free(p->pnext);
p->pnext = NULL;
plink->clen--;
}
查找
int find_data(Link_t *plink,DataType data)
{
int i = 1;
Link_Node_t *p = plink->phead;
while(p->pnext != NULL)
{
if(data == p->data)
{
break;
}
p = p->pnext;
++i;
if(p == NULL)
{
return 0;
}
}
return i;
}
替换
int change_link(Link_t *plink,DataType date,DataType data)
{
int i= 1;
int ret = find_data(plink,date);
Link_Node_t *p = plink->phead;
while(p->pnext != NULL)
{
if(i == ret)
{
p->data = data;
}
p = p->pnext;
i++;
}
}