数据结构(栈、顺序表、队列、链式表)

什么是数据结构

​ 是一门研究数据之间关系的一门学科,主要有两类需要研究的关系:逻辑关系、物理关系

​ 物理关系:数据在内存中的实际关系。

​ 顺序结构:根据数据之间的相对位置确定关系

​ 链式结构:在数据当中再添加一个指针域,用于指向跟它有关系的数据。

​ 逻辑关系:无视物理关系,人为添加的一种关系。

​ 集合:数据之间同属一个集体,除此之外没有任何关系。

​ 表:数据之间存在一对一关系,如:数组(顺序表),链表(链式表)。

​ 树:数据之间存在一对多关系。

​ 图:数据之间存在多对多关系。

​ 注意:我们常说的数据结构指的是逻辑关系,而数据结构在内存中的储存方式,指的是物理关系。

​ 每种逻辑关系采用什么样的物理结构储存并没有明确规定,通常以代码实现的验证、以及时间、空间复杂度的要求,选择最合适的物理结构储存,也有可能是链式和顺序混合存储。

算法

​ 广义:解决特定问题的方法

​ 狭义:数据结构的运算

学习数据结构的三个关键点

​ 1、物理结构

​ 2、逻辑结构:所有的逻辑结构既可以是顺序结构存在,也可以是链式结构存在。

​ 3、结构的运算

数据结构常有的运算:

​ 1、创建数据结构:create

​ 2、销毁数据结构:destroy

​ 3、清除所有元素:clear

​ 4、遍历数据结构:show、print

​ 5、从数据结构中删除一个元素:delete

​ 6、把一个元素插入到数据结构:install

​ 7、修改数据结构中的某个元素:modify

​ 8、查询数据结构中的元素:query、find

​ 9、访问其中一个元素:access

顺序表

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define TYPE int

//设计顺序表结构:元素之间是连续的
typedef struct Order
{
	TYPE* ptr;
	int cal;
	int cnt;
}Order;

//创建顺序表
Order* create_order(int cal)
{
	//给表结构分配内存
	Order* order = malloc(sizeof(Order));
	//给元素分配内存
	order->ptr = malloc(sizeof(TYPE)*cal);
	//记录表的容量
	order->cal = cal;
	//初始化元素的数量
	order->cnt = 0;
	return order;
}

//销毁顺序表
void destroy_order(Order* order)
{
	free(order->ptr);
	order->ptr=NULL;
	free(order);
	order = NULL;
}

//清除表元素
void clear_order(Order* order)
{
	order->cnt = 0;
}

//插入元素
bool insert_order(Order* order,int index,TYPE val)
{
	if(order->cnt >= order->cal || index >= order->cnt)
	{
		return false;
	}
	for(int i=order->cnt; i>index; i--)
	{
		order->ptr[i] = order->ptr[i-1];
	}
	order->ptr[index] = val;
	order->cnt++;
	return true;
}

//删除元素
bool delete_order(Order* order,int index)
{
	if(index >= order->cnt)
	{
		return false;
	}
	for(int i=0; i<order->cnt-1; i++)
	{
		order->ptr[i] = order->ptr[i+1];
	}
	order->cnt--;
	return true;
}

//添加元素
bool add_order(Order* order,TYPE val)
{
	//判断表是否满
	if(order->cnt >= order->cal)
	{
		return false;
	}
	//在末尾添加元素
	order->ptr[order->cnt++] = val;
	return true;
}

//访问元素
bool access_order(Order* order,int index,TYPE* p)
{
	if(index >= order->cnt)
	{
		return false;
	}
	*p = order->ptr[index];
	return true;
}

//修改元素
bool modify_order(Order* order,TYPE old,TYPE new)
{
	for(int i=0; i<order->cnt; i++)
	{
		if(order->ptr[i] == old)
		{
			order->ptr[i] = new;
			return true;
		}
	}
	return false;
}

//查询元素
int query_order(Order* order,TYPE key)
{
	for(int i=0; i<order->cnt; i++)
	{
		if(key == order->ptr[i])
		{
			return i;
		}
	}
	return -1;
}
//遍历顺序表
void show_order(Order* order)
{
	for(int i=0; i<order->cnt; i++)
	{
		printf("%d ",order->ptr[i]);
	}
	printf("\n");
}
//排序顺序表
void sort_order(Order* order)
{
	for(int i=0; i<order->cnt-1; i++)
	{
		for(int j=i+1; j<order->cnt; j++)
		{
			if(order->ptr[j] > order->ptr[i])
			{
				TYPE temp = order->ptr[i];
				order->ptr[i] = order->ptr[j];
				order->ptr[j] = temp;
			}
		}
	}
}
int main(int argc,const char* argv[])
{
	Order* order = create_order(15);
	for(int i=0; i<10; i++)
	{
		add_order(order,rand()%100);
	}
	show_order(order);
	insert_order(order,1,10001);
	show_order(order);
	delete_order(order,1);
	show_order(order);
	int num=0;
	access_order(order,0,&num) && printf("access:%d",num);
	sort_order(order);
	show_order(order);
}

功能被限制的表

​ 只有一个端口进入,元素先进后出FILO

​ 而栈内存正是使用了这种结构管理内存,所以才叫栈内存

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TYPE int


typedef struct StackOrder
{
	TYPE* ptr;
	int cal;
	int top;
}StackOrder;

//创建桟
StackOrder* create_stack(int cal)
{
	StackOrder* stack = malloc(sizeof(StackOrder));
	stack->ptr = malloc(sizeof(TYPE)*cal);
	stack->cal = cal;
	stack->top = -1; //cal|cal-1|0|-1
	/*
		cal:满减桟
		cal-1:空减桟
		-1:满增桟
		0:空增桟
	*/
	return stack;
}
//销毁桟
void destroy_stack(StackOrder* stack)
{
	free(stack->ptr);
	free(stack);
}
//桟空
bool empty_stack(StackOrder* stack)
{
	return -1 == stack->top;
}
//桟满
bool full_stack(StackOrder* stack)
{
	return stack->top >= stack->cal-1;
}
//入桟
bool push_stack(StackOrder* stack,TYPE val)
{
	if(full_stack(stack))
		return false;
	stack->ptr[++stack->top] = val;
	return true;
}
//出桟
bool pop_stack(StackOrder* stack)
{
	if(empty_stack(stack))
		return false;
	stack->top--;
	return true;
}
//获取栈顶元素
TYPE top_stack(StackOrder* stack)
{
	return stack->ptr[stack->top];
}
int main(int argc,const char* argv[])
{
	StackOrder* stack = create_stack(10);
	for(int i=0; i<11; i++)
	{
		bool flag = push_stack(stack,i);
		printf("push:%d %s\n",i,flag?"成功":"失败");
	}
	while(!empty_stack(stack))
	{
		printf("top:%d ",top_stack(stack));
		printf("%s\n",pop_stack(stack)?"成功":"失败");
	}
}

队列

把一个表结构限制成有两个端口,一个端口只能进,另一个端口只能出,先进先出FIFO

​ 队头 0

​ 队尾 0

​ 队空 队头==队尾

​ 队满 队尾+1==队头

​ 出队 front = (front+1)%cal

​ 入队 rear = (rear+1)%cal

​ 队头元素 ptr[front]

​ 队尾元素 (cal+rear-1)%cal

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TYPE int

typedef struct QueueOrder
{
	TYPE* ptr;
	int cal;
	int front;
	int rear;
}QueueOrder;


//创建队列
QueueOrder* create_queue(int cal)
{
	QueueOrder* queue = malloc(sizeof(QueueOrder));
	queue->ptr = malloc(sizeof(TYPE)*cal);
	queue->cal = cal;
	queue->front = 0;
	queue->rear = 0;
	return queue;
}

//销毁队列
void destroy_queue(QueueOrder* queue)
{
	free(queue->ptr);
	free(queue);
}

//队空
bool empty_queue(QueueOrder* queue)
{
	return queue->front == queue->rear;
}

//队满
bool full_queue(QueueOrder* queue)
{
	return (queue->rear+1)%queue->cal == queue->front;
}

//入队
bool push_queue(QueueOrder* queue,TYPE val)
{
	if(full_queue(queue))
		return false;
	queue->ptr[queue->rear] = val;
	queue->rear = (queue->rear+1)%queue->cal;
	return true;
}

//出队
bool pop_queue(QueueOrder* queue)
{
	if(empty_queue(queue))
		return false;
	queue->front = (queue->front+1)%queue->cal;
	return true;
}

//队头
TYPE front_queue(QueueOrder* queue)
{
	return queue->ptr[queue->front];
}

//队尾
TYPE rear_queue(QueueOrder* queue)
{
	if(queue->rear)
		return queue->ptr[queue->rear-1];
	else
		return queue->ptr[queue->cal-1];
	//return queue->ptr[(queue->rear+queue->cal-1)%queue->cal];
}

int main(int argc,const char* argv[])
{
	QueueOrder* queue = create_queue(10);
	for(int i=0; i<10; i++)
	{
		push_queue(queue,i);
		printf("rear:%d\n",rear_queue(queue));
	}
	while(!empty_queue(queue))
	{
		printf("front:%d\n",front_queue(queue));
		pop_queue(queue);
	}
}

链式表

​ 元素:由数据域,指针域组成,元素之间使用指针域链接,这种结构叫链式存储结构。

​ 如果元素中只有一个指针域,且指向下一个元素,这样元素之间就只存在一对一关系,这种结构叫链式表。

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TYPE int

//链表的节点
typedef struct Node
{
	TYPE data;	//数据域
	struct Node* next;	//指针域,指向下一个节点
}Node;

//创建节点
Node* create_node(TYPE data)
{
	Node* node = malloc(sizeof(Node));
	node->data = data;
	node->next = NULL;
	return node;
}

//链表
typedef struct List
{
	Node* head;
	Node* tail;
}List;

//创建链表
List* create_list(void)
{
	List* list = malloc(sizeof(List));
	list->head = NULL;
	list->tail = NULL;
}

//头添加节点
void add_head_list(List* list,TYPE data)
{
	Node* node = create_node(data);
	if(NULL == list->head)
	{
		list->head = node;
		list->tail = node;
	}
	else
	{
		node->next = list->head;
		list->head = node;
	}
}
//尾添加节点
void add_tail_list(List* list,TYPE data)
{
	Node* node = create_node(data);
	if(NULL == list->tail)
	{
		list->head = node;
		list->tail = node;
	}
	else
	{
		list->tail->next = node;
		list->tail = node;
	}
}

//头删除节点
void del_head_list(List* list)
{	Node* node = list->head;
	if(list->tail == list->head)
	{
		list->head = NULL;
		list->tail = NULL;
	}
	else
	{
		list->head = node->next;
	}
	free(node);
}
//尾删除节点
void del_tail_list(List* list)
{
	Node* node = list->tail;
	if(list->tail == list->head)
	{
		list->head = NULL;
		list->tail = NULL;
	}
	else
	{
		Node* prev = list->head;
		while(prev->next != list->tail)
		{
			prev = prev->next;
		}
		prev->next = NULL;
		list->tail = prev;	
	}
	free(node);
}
//修改
bool modify_list(List* list,TYPE old,TYPE new)
{
	for(Node* n=list->head; NULL!=n; n=n->next)
	{
		if(n->data == old)
		{
			n->data = new;
			return true;
		}
	}
	return false;
}
//查询
bool query_list(List* list,TYPE key)
{
	for(Node* n=list->head; NULL!=n; n=n->next)
	{
		if(key == n->data)
		{
			return true;
		}
	}
	return true;
}
//长度
size_t len_list(List* list)
{
	int len = 0;
	for(Node* n=list->head; NULL!=n; n=n->next)
	{
		len++;
	}
	return len;
}

//遍历
void show_list(List* list)
{
	for(Node* n=list->head; NULL!=n; n=n->next)
	{
		printf("%d ",n->data);
	}
	printf("\n");
}
//排序
void sort_list(List* list)
{
	for(Node* n1=list->head; list->tail!=n1->next; n1=n1->next)
	{
		for(Node* n2=n1->next; NULL!=n2; n2=n2->next)
		{
			if(n1->data < n2->data)
			{
				TYPE temp = n1->data;
				n1->data = n2->data;
				n2->data = temp;
			}
		}
	}
}

int main(int argc,const char* argv[])
{
	List* list = create_list();
	for(int i=0; i<15; i++)
	
	{
		add_tail_list(list,i);
	}
	show_list(list);
	del_tail_list(list);
	show_list(list);
	modify_list(list,7,100);
	show_list(list);
	printf("len:---%d---",len_list(list));
	sort_list(list);
	show_list(list);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值