数据结构的四种基本类型
-
集合:元素之间没有任何关系
-
线性表:元素之间存在一对一关系
数组、链表、功能受限的表(栈、队列) -
树:元素之间存在一对多关系
普通树、二叉树、完全二叉树、满二叉树、有序二叉树 -
图:元素之间存在多对多关系
邻接表、表的遍历(深度优先、广度优先)、最短路径
数据结构的存储方式(物理结构)
-
顺序:再一块连续的内存空间上存储元素与元素之间的关系。
优点是查找速度快(随机访问),不易产生内存碎片。缺点是对内存要求高,添加和删除不方便。 -
非顺序:元素随机存储内存空间中,元素中存储指向其他元素的地址。
有点是对内存要求低,添加删除方便,查找速度慢(只能从头逐个遍历),容易产生内存碎片。
栈:限制为只有一个端口进出元素,就导致先进后出的特性。
一般常用于,表达式解析,内存管理(函数的调用提供支持)。
顺序栈的实现
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TYPE int
typedef struct Stack
{
TYPE* arr;//内存首地址
size_t len;//栈的内容
int top;//栈顶的下标
}Stack;
//创建
Stack* creat_stack(size_t cal);
//销毁
void destory_stack(Stack* stack);
//入栈
bool push_stack(Stack *stack,TYPE data);
//出栈
bool pop_stack(Stack* stack);
//栈空
bool empty_stack(Stack* stack);
//栈满
bool full_stack(Stack* stack);
//栈顶
TYPE* top_stack(Stack* stack);
int main()
{
Stack* stack = creat_stack(15);
printf("开始入栈\n");
for(int i= 0 ;i<20;i++)
{
printf("入栈%s",push_stack(stack,i)?"成功":"失败");
printf("栈顶%d\n",*top_stack(stack));
}
printf("开始出栈\n");
for(int i= 19 ;i>=0;i--)
{
printf("出栈%s",pop_stack(stack)?"成功":"失败");
printf("栈顶%d\n",*top_stack(stack));
}
}
//创建
Stack* creat_stack(size_t cal)
{
Stack* stack = malloc(sizeof(Stack));
stack->arr = malloc(sizeof(TYPE)*cal);
stack->len = cal;
stack->top =-1;
return stack;
}
//销毁
void destory_stack(Stack* stack)
{
free(stack->arr);
free(stack);
}
//入栈
bool push_stack(Stack *stack,TYPE data)
{
if(full_stack(stack)) return false;
stack->arr[++stack->top]=data;
return true;
}
//出栈
bool pop_stack(Stack* stack)
{
if (empty_stack(stack)) return false;
stack->arr[--stack->top];
return true;
}
//栈空
bool empty_stack(Stack* stack)
{
return-1 == stack->top;
}
//栈满
bool full_stack(Stack* stack)
{
return (stack->top+1 >= stack->len);
}
//栈顶
TYPE* top_stack(Stack* stack)
{
if(empty_stack(stack)) return NULL;
return stack->arr+stack->top;
}
链式栈的实现
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TYPE int
typedef struct Node
{
TYPE data;
struct Node* next;
}Node;
Node* creat_node(TYPE data)
{
Node* node = malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
typedef struct Stack
{
Node* top;
size_t len;
}Stack;
//创建
Stack* creat_stack(void);
//销毁
void destory_stack(Stack* stack);
//栈空
bool empty_stack(Stack* stack);
//入栈
void push_stack(Stack* stack,TYPE data);
//出栈
bool pop_stack(Stack* stack);
//栈顶
TYPE* top_stack(Stack* stack);
int main()
{
Stack* stack = creat_stack();
for (int i=0;i<10;i++)
{
push_stack(stack,i);
printf("top:%d\n",*top_stack(stack));
}
printf("------------\n");
for (int i=0;i<10;i++)
{
printf("top:%d\n",*top_stack(stack));
printf("出栈%s\n",pop_stack(stack)?"成功":"失败");
}
}
//创建
Stack* creat_stack(void)
{
Stack* stack=malloc(sizeof(Stack));
stack->top = NULL;
stack->len = 0;
return stack;
}
//销毁
void destory_stack(Stack* stack)
{
while(pop_stack(stack));
free(stack);
}
//栈空
bool empty_stack(Stack* stack)
{
return NULL == stack->top;
}
//入栈
void push_stack(Stack* stack,TYPE data)
{
Node* node = creat_node(data);
node->next = stack->top;
stack->top = node;
stack->len++;
}
//出栈
bool pop_stack(Stack* stack)
{
if(empty_stack(stack)) return false;
Node* node = stack->top;
stack->top = node->next;
free(node);
stack->len--;
return true;
}
//栈顶
TYPE* top_stack(Stack* stack)
{
if(empty_stack(stack)) return NULL;
return &stack->top->data;
}
队列:限制为有个端口进出元素,一个只管进,另一个只管出,就导致先进先出特性。
顺序队列的实现
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TYPE int
typedef struct Queue
{
TYPE* base;
int size;
int head; //队头
int tall; //队尾
int cnt; //数量
}Queue;
//创建
Queue * creat_queue(int len);
//销毁
void destory_queue(Queue* queue);
//队空
bool empty_queue(Queue* queue);
//队满
bool full_queue(Queue* queue);
//入队
bool push_queue(Queue* queue,TYPE data);
//出队
bool pop_queue(Queue* queue);
//队头
TYPE* head_queue(Queue* queue);
//队尾
TYPE* tall_queue(Queue* queue);
int main()
{
Queue* queue =creat_queue(10);
for (int i=0;i<10;i++)
{
printf("入队%s,",push_queue(queue,i)?"成功":"失败");
printf("队尾:%d\n",*tall_queue(queue));
}
for(int i=0;i<5;i++)
{
printf("队头:%d,",*head_queue(queue));
printf("出队%s\n",pop_queue(queue)?"成功":"失败");
}
for (int i=77;i<88;i++)
{
printf("入队%s,",push_queue(queue,i)?"成功":"失败");
printf("队尾:%d\n",*tall_queue(queue));
}
}
//创建
Queue * creat_queue(int len)
{
Queue* queue=malloc(sizeof(Queue));
queue->base=malloc(sizeof(TYPE)*len);
queue->size=len;
queue->head=0;
queue->tall=-1;
queue->cnt=0;
return queue;
}
//销毁
void destory_queue(Queue* queue)
{
free(queue->base);
free(queue);
}
//队空
bool empty_queue(Queue* queue)
{
return !queue->cnt;
}
//队满
bool full_queue(Queue* queue)
{
return queue->cnt>=queue->size;
}
//入队
bool push_queue(Queue* queue,TYPE data)
{
//判断是否队满
//回头
if (full_queue(queue)) return false;
queue->tall = (queue->tall+1) % queue->size;
queue->base[queue->tall] =data;
queue->cnt++;
return true;
}
//出队
bool pop_queue(Queue* queue)
{
//判断是否对空
//回头
if (empty_queue(queue)) return false;
queue->head = (queue->head+1) % queue->size;
queue->cnt--;
return true;
}
//队头
TYPE* head_queue(Queue* queue)
{
if (empty_queue(queue)) return NULL;
return queue->base+queue->head;
}
//队尾
TYPE* tall_queue(Queue* queue)
{
if (empty_queue(queue)) return NULL;
return queue->base+queue->tall;
}
链式队列的实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
typedef struct Node
{
TYPE data;
struct Node* next;
}Node;
Node* creat_node(TYPE data)
{
Node* node = malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
typedef struct Queue
{
Node* head;
Node* tail;
size_t size;
}Queue;
//创建
Queue* creat_queue(void);
//销毁
void destory_queue(Queue* queue);
//入队
void push_queue(Queue* queue,TYPE* data);
//出队
bool pop_queue(Queue* queue);
//查看队头
TYPE* head_queue(Queue* queue);
//查看队尾
TYPE* tail_queue(Queue* queue);
//队空
bool empty_queue(Queue* queue);
int main()
{
Queue* queue =creat_queue();
for (int i=0;i<10;i++)
{
printf("入队%s,",push_queue(queue,i)?"成功":"失败");
// printf("队尾:%d\n",*tall_queue(queue));
}
for(int i=0;i<5;i++)
{
// printf("队头:%d,",*head_queue(queue));
printf("出队%s\n",pop_queue(queue)?"成功":"失败");
}
}
//创建
Queue* creat_queue(void)
{
Queue* queue = malloc(sizeof(Queue));
queue->head = NULL;
queue->tail = NULL;
queue->size = 0;
}
//销毁
void destory_queue(Queue* queue)
{
while(pop_queue(queue));
free(queue);
}
//入队
void push_queue(Queue* queue,TYPE* data)
{
Node* node = creat_node(data);
if (0 == queue->size)
{
queue->head = node;
queue->tail = node;
}
else
{
queue->tail->next = node;
queue->tail = node;
}
queue->size++;
}
//出队
bool pop_queue(Queue* queue)
{
if (empty_queue(queue)) return false;
Node* temp = queue->head;
if (1 === queue->size)
{
queue->tail = NULL;
}
while(temp->next != queue->tail)
{
temp = temp->next;
}
free(queue->tail);
queue->tail = temp;
temp->next = NULL;
queue->size--;
}
//查看队头
TYPE* head_queue(Queue* queue);
//查看队尾
TYPE* tail_queue(Queue* queue);
//队空
bool empty_queue(Queue* queue)
{
return !queue->size;
}
表:每个元素都独立存储在内存中的任意位置,元素之间由指针指向来维护关系。
顺序表的实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
//设计数据结构
typedef struct Array
{
TYPE* base; //数组首地址
size_t size; //元素的个数
}Array;
//创建
Array*create_array(size_t len);
//销毁
void destory_array(Array* arr);
//访问
TYPE* access_array(Array* arr,int index);
//查找
int find_array(Array*arr,TYPE data);
//排序
void sort_array(Array* arr);
//遍历
void show_array(Array* arr);
//删除
bool delete_array(Array* arr,int index);
//插入
bool insert_array(Array* arr,int index,TYPE data);
int main()
{
Array* arr=create_array(20);
for(int i=0;i<20;i++)
{
//*access_array(arr,i)=rand() % 100;
TYPE* p=access_array(arr,i);
if (NULL!=p)
*access_array(arr,i)=rand() % 100;
}
show_array(arr);
sort_array(arr);
show_array(arr);
delete_array(arr,4);
show_array(arr);
}
//创建
Array*create_array(size_t len)
{
Array* arr=malloc(sizeof(Array));
arr->base=malloc(sizeof(TYPE)*len);
arr->size=len;
return arr;
}
//销毁
void destory_array(Array* arr)
{
free(arr->base);
free(arr);
}
//访问
TYPE* access_array(Array* arr,int index)
{
if (index<0|index>=arr->size) return NULL;
return arr->base+index;
}
//查找
int find_array(Array*arr,TYPE data)
{
for(int i=0;i<arr->size;i++)
{
if (data = arr->base[i])
return i;
}
return -1;
}
//排序
void sort_array(Array* arr)
{
for(int i=0;i<arr->size-1;i++)
{
for(int j=i+1;j<arr->size;j++)
{
if (arr->base[i]>arr->base[j])
{
TYPE temp=arr->base[i];
arr->base[i]=arr->base[j];
arr->base[j]=temp;
}
}
}
}
//遍历
void show_array(Array* arr)
{
for(int i=0;i<arr->size;i++)
{
printf("%d ",arr->base[i]);
}
printf("\n");
}
//删除
bool delete_array(Array* arr,int index)
{
if (index<0 |index>arr->size) return false;
for (int i=index;i<arr->size-1;i++)
{
arr->base[i]=arr->base[i+1];
}
return true;
}
//插入
bool insert_array(Array* arr,int index,TYPE data)
{
if (index<0 |index>arr->size) return false;
for (int i=arr->size-1;i<index;i--)
{
arr->base[i]=arr->base[i-1];
}
arr[index]=data;
return true;
}
链式表的实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
typedef struct Node
{
TYPE data;
struct Node* next;
}Node;
// 创建节点
Node* creat_node(TYPE data)
{
Node* node = malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
typedef struct List
{
Node* head;
Node* tail;
size_t size;
}List;
// 创建
List* creat_list(void);
// 销毁
void destory_list(List* list);
// 头添加
void head_add_list(List* list,TYPE data);
// 尾添加
void tail_add_list(List* list,TYPE data);
// 头删除
bool head_del_list(List* list);
// 尾删除
bool tail_del_list(List* list);
// 插入
bool insert_list(List* list,int index,TYPE data);
// 位置删除
bool delete_index_list(List* list,int index);
// 值删除
bool delete_value_list(List* list,TYPE data);
// 排序
void sort_list(List* list);
// 遍历
void show_list(List* list);
int main()
{
List* list = creat_list();
for(int i=0; i<10; i++)
{
//tail_add_list(list,i);
head_add_list(list,i);
}
show_list(list);
delete_index_list(list,9);
delete_index_list(list,0);
//insert_list(list,-1,100);
show_list(list);
/*
show_list(list);
sort_list(list);
show_list(list);
for(int i=0; i<5; i++)
{
head_del_list(list);
}
show_list(list);
*/
}
// 创建
List* creat_list(void)
{
List* list = malloc(sizeof(List));
list->head = NULL;
list->tail = NULL;
return list;
}
// 销毁
void destory_list(List* list)
{
while(0 < list->size)
{
head_del_list(list);
}
free(list);
}
// 头添加
void head_add_list(List* list,TYPE data)
{
Node* node = creat_node(data);
if(0 == list->size)
{
list->head = node;
list->tail = node;
}
else
{
node->next = list->head;
list->head = node;
}
list->size++;
}
// 尾添加
void tail_add_list(List* list,TYPE data)
{
Node* node = creat_node(data);
if(0 == list->size)
{
list->head = node;
list->tail = node;
}
else
{
list->tail->next = node;
list->tail = node;
}
list->size++;
}
// 头删除
bool head_del_list(List* list)
{
if(0 >= list->size) return false;
Node* temp = list->head;
list->head = temp->next;
if(1 == list->size)
{
list->tail = NULL;
}
free(temp);
list->size--;
return true;
}
// 尾删除
bool tail_del_list(List* list)
{
if(0 >= list->size) return false;
if(1 == list->size)
{
head_del_list(list);
return true;
}
Node* prev = list->head;
while(prev->next != list->tail)
{
prev = prev->next;
}
free(list->tail);
list->tail = prev;
prev->next = NULL;
list->size--;
return true;
}
// 插入
bool insert_list(List* list,int index,TYPE data)
{
if(index < 0 || index >= list->size) return false;
if(0 == index)
{
head_add_list(list,data);
return true;
}
Node* prev = list->head;
for(int i=0; i<index-1; i++)
{
prev = prev->next;
}
Node* node = creat_node(data);
node->next = prev->next;
prev->next = node;
list->size++;
return true;
}
// 位置删除
bool delete_index_list(List* list,int index)
{
if(index < 0 || index >= list->size) return false;
if(0 == index)
head_del_list(list);
else if(list->size == index+1)
tail_del_list(list);
else
{
Node* prev = list->head;
for(int i=0; i<index-1; i++)
{
prev = prev->next;
}
Node* node = prev->next;
prev->next = node->next;
free(node);
list->size--;
}
return true;
}
// 值删除
bool delete_value_list(List* list,TYPE data)
{
if(data == list->head->data)
{
head_del_list(list);
return true;
}
Node* prev = list->head;
while(NULL!=prev->next)
{
if(data == prev->next->data)
{
Node* node = prev->next;
prev->next = node->next;
free(node);
list->size--;
return true;
}
prev = prev->next;
}
return false;
}
// 排序
void sort_list(List* list)
{
for(Node* i=list->head; NULL != i->next; i=i->next)
{
for(Node* j=i->next; NULL != j; j=j->next)
{
if(i->data > j->data)
{
TYPE temp = i->data;
i->data = j->data;
j->data = temp;
}
}
}
}
// 遍历
void show_list(List* list)
{
for(Node* node=list->head; NULL!=node; node=node->next)
{
printf("%d ",node->data);
}
printf("\n");
}
双向链表的实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
typedef struct Node
{
struct Node* prev; // 前一个元素
TYPE data; // 数据
struct Node* next; // 后一个元素
}Node;
// 创建节点
Node* creat_node(TYPE data)
{
Node* node = malloc(sizeof(Node));
node->prev = NULL;
node->data = data;
node->next = NULL;
return node;
}
typedef struct List
{
Node* head;
Node* tail;
size_t size;
}List;
// 创建
List* creat_list(void);
// 销毁
void destory_list(List* list);
// 头加
void head_add_list(List* list,TYPE data);
// 尾加
void tail_add_list(List* list,TYPE data);
// 插入
bool insert_list(List* list,int index,TYPE data);
// 位置删除
bool delete_index_list(List* list,int index);
// 值删除
bool delete_value_list(List* list,TYPE data);
// 遍历
void show_list(List* list);
bool del_head_list(List* list);
bool del_tail_list(List* list);
int main()
{
List* list = creat_list();
for(int i=0; i<10; i++)
{
tail_add_list(list,i);
}
insert_list(list,1,100);
show_list(list);
delete_value_list(list,0);
delete_value_list(list,100);
delete_value_list(list,9);
show_list(list);
destory_list(list);
}
// 创建
List* creat_list(void)
{
List* list = malloc(sizeof(List));
list->head = NULL;
list->tail = NULL;
list->size = 0;
return list;
}
// 销毁
void destory_list(List* list)
{
while(list->size>0)
{
del_tail_list(list);
}
free(list);
}
// 头加
void head_add_list(List* list,TYPE data)
{
Node* node = creat_node(data);
if(0 == list->size)
{
list->head = node;
list->tail = node;
}
else
{
node->next = list->head;
list->head->prev = node;
list->head = node;
}
list->size++;
}
// 尾加
void tail_add_list(List* list,TYPE data)
{
Node* node = creat_node(data);
if(0 == list->size)
{
list->head = node;
list->tail = node;
}
else
{
list->tail->next = node;
node->prev = list->tail;
list->tail = node;
}
list->size++;
}
// 插入
bool insert_list(List* list,int index,TYPE data)
{
if(index < 0 || index >= list->size) return false;
if(0 == index)
{
head_add_list(list,data);
return true;
}
Node* next = NULL;
if(index < list->size/2)
{
next = list->head;
for(int i=0; i<index; i++)
{
next = next->next;
}
}
else
{
next = list->tail;
for(int i=list->size-1; i>index; i--)
{
next = next->prev;
}
}
Node* prev = next->prev;
Node* node = creat_node(data);
node->next = next;
node->prev = prev;
prev->next = node;
next->prev = node;
list->size++;
return true;
}
// 删除头
bool del_head_list(List* list)
{
if(list->size <= 0) return false;
Node* node = list->head;
if(1 == list->size)
{
list->head = NULL;
list->tail = NULL;
}
else
{
list->head = node->next;
node->next->prev = NULL;
}
free(node);
list->size--;
return true;
}
// 删除尾
bool del_tail_list(List* list)
{
if(list->size <= 0) return false;
Node* node = list->tail;
if(1 == list->size)
{
list->head = NULL;
list->tail = NULL;
}
else
{
list->tail = node->prev;
node->prev->next = NULL;
}
free(node);
list->size--;
return true;
}
// 位置删除
bool delete_index_list(List* list,int index)
{
if(index < 0 || index >= list->size) return false;
if(0 == index) return del_head_list(list);
if(list->size-1 == index) return del_tail_list(list);
Node* node = NULL;
if(index < list->size/2)
{
node = list->head;
for(int i=0; i<index; i++)
{
node = node->next;
}
}
else
{
node = list->tail;
for(int i=list->size-1; i>index; i--)
{
node = node->prev;
}
}
Node* prev = node->prev;
Node* next = node->next;
prev->next = next;
next->prev = prev;
free(node);
list->size--;
return true;
}
// 值删除
bool delete_value_list(List* list,TYPE data)
{
if(data == list->head->data)
return del_head_list(list);
if(data == list->tail->data)
return del_tail_list(list);
Node* node = list->head;
while(NULL != node)
{
if(data == node->data) break;
node = node->next;
}
Node* prev = node->prev;
Node* next = node->next;
prev->next = next;
next->prev = prev;
free(node);
list->size--;
return true;
}
// 遍历
void show_list(List* list)
{
for(Node* i=list->head; i!=NULL; i=i->next)
{
printf("%d ",i->data);
}
printf("\n");
for(Node* i=list->tail; i!=NULL; i=i->prev)
{
printf("%d ",i->data);
}
printf("\n");
}