常用的数据结构(1)链表、队列、栈

计算机科学家Nikiklaus Wirth曾提出“数据结构+算法=程序”的著名公式,数据结构的重要性不言而喻。之所以数据结构如此重要,就是因为不同的数据结构采用的处理方法不同,计算复杂度也往往不同。所以良好的算法必须依赖于某种合适的数据结构,才能够发挥最大的效用。

我们常用的数据结构主要有以下几种:数组(Array)、(Stack),队列(Queue)、链表(Linked List)、树(Tree)、(Graph)、(Heap)和散列(Hash)。按照数据的逻辑结构对其进行简单的分类,可以分为线性(栈、队列等)和非线性(树、图等)结构两类。

 链表结构:

顾名思义,就是把各个数据点串联起来形成一个链条一样的结构,典型的链表结构包括数据部分和地址部分。

数据部分:保存该节点的实际数据

地址部分:保存下一节点的地址

进行链表结构操作是时,必须知道链表的“头指针”,因此我们在创建链表时也要首先定义一个“头指针”,头指针指向第一个节点的地址,第一个节点的地址部分又指向第二个节点,以此类推,最后一个节点的地址部分应该存放一个空地址NULL。以将数组转化为链表为例、基于C的链表的一些操作代码如下

#include<stdio.h>
#include<stdlib.h>
const int maxn=10;
struct node
{
	int data;            //数据部分 
	node* next;          //指向下一个节点的地址 
};

void insert(node* &head,int data)    //插入节点函数 
{
	node *head_temp=new node;        //分配临时 
	if(head==NULL)                   //头节点为NULL 
	{
		head_temp->data=data;        //创建第一个节点数据 
		head_temp->next=NULL;        //节点的下一个地址设置为NULL 
		head=head_temp;              //将头节点的地址指向第一个节点          
		return;
	}
	else                               
	{
		node *next=new node;          //分配临时节点内存 
		head_temp=head;                
		while(head_temp->next!=NULL)
		{
			head_temp=head_temp->next;
		}
		next->data=data;
		next->next=NULL;
		head_temp->next=next;         //将链表尾节点的next地址设置为新节点的地址 
	}
	return;
} 
void Creat(node* &head,int *data)     //创建链表函数 
{
	for(int i = 0;i < 10;i++)
	{
		insert(head,data[i]);	     //调用insert函数 
	}
	return;
} 
int main()
{	
	       
	node *head=new node;                    //分配头结点内存 
	head=NULL;                             //头节点内存设置为NULL 
	int data[]={1,2,3,4,5,6,7,8,9,0};      //设置测试数组 
	Creat(head,data);                      //调用创建链表函数 
	node *head_t=new node;                 //分配临时节点内存 
	head_t=head;
	while(head_t!=NULL)                    //将每个节点的与元素打印 
	{
		printf("%d ",head_t->data);
		head_t=head_t->next;
	}	
} 

栈结构:

栈结构的特点可以概括为“先进的后出,后进的先出”。生活中很多栈结构的例子。例如:如果一个仓库只有一个门,当仓库中退房货物时,最先进来的货物只能堆放到最里面,后来的货放在外面;而要取出货物,总是先取出最外面的。

栈结构的基本操作只有两个

入栈

出栈

同样以一组数组为例进行栈的基本操作,代码如下:

#include<stdio.h>
#include<stdlib.h>
const int maxn=10;
struct DATA         //定义结构体 
{
	int num;
};
struct Stack        
{
	DATA data[maxn];     //栈内元素为结构体DATA 
	int top;             //栈顶指针 
};
Stack *init()            //初始化栈 
{
	Stack *p;
	if(p=(Stack *)malloc(sizeof(Stack)));
	{
		p->top=0;
		return p;
	}
}
void PushStack(Stack* &s,int data)    //入栈 
{
	if(s->top>maxn-1)
	{
		printf("溢出\n");
	}
	s->data[s->top++].num=data;       //栈顶指针上移 
}
DATA PopStack(Stack* &s)               //出栈 
{
	if(s->top<0)
	{
		printf("栈为空\n");
		exit(0);
	}
	s->top--;                         //栈顶指针下移 
	return s->data[s->top];	
}
DATA GetStackElement(Stack *s)
{
	if(s->top<0)
	{
		printf("栈为空\n");
		exit(0);
	}
	return s->data[s->top-1];
}
int main()
{
	int data[]={1,2,3,4,5,6,7,8,9,0}; 
	Stack *s;
	s=init();                                      //初始化 
	for(int i=0;i<10;i++)
	{
		PushStack(s,data[i]);                     //将数组元素入栈 
	}
	while(s->top>0)
	{
		printf("*%d\n",GetStackElement(s).num);  //获取栈顶元素 
		PopStack(s);                             //栈顶元素弹出 
	} 
	
}

队列结构:

队列是源于生活的一种数据结构,如果说栈结构只有一个进口,那么队列结构有一个进口和一个出口。相比于栈结构的“先进的后出,后进的先出”,队列的特征则是“先进的先出,后进的后出”。一般队列的操作只有两个:

入队和出队,同样以一维数组为例进行队列的基本操作:

#include<stdio.h>
#include<stdlib.h>
const int maxn=10;
struct DATA         //定义结构体 
{
	int num;
};
struct queue        
{
	DATA data[maxn];     //队列内元素为结构体DATA 
	int head;            //队列头 
	int tail;            //队列尾 
};
queue *init()            //初始化队列 
{
	queue *q;
	if(q=(queue *)malloc(sizeof(queue)));
	{
		q->head=0;        //初始化队列为空 头尾均为0 
		q->tail=0;
		return q;
	}
}
void InQueue(queue* &q,int data)    //入队列 
{
	if(q->tail==maxn)
	{
		printf("队列满了\n");
	}
	else
	{
		q->data[q->tail++].num=data;      //尾++ 
	} 
}
DATA OutQueue(queue* &q)           
{
	if(q->head==q->tail)
	{
		printf("队列已空\n");
	}
	else
	{
		return q->data[q->head++];      //头++ 
	}
}
DATA GetQueueElement(queue *q)
{
	if(q->head==q->tail)                 //头尾相等时 队列为空 
	{
		printf("队列已空\n");
	}
	else
	{
		return q->data[q->head];
	}
}
int main()
{
	int data[]={1,2,3,4,5,6,7,8,9,0}; 
	queue *q;
	q=init();                         //初始化 
	for(int i=0;i<10;i++)
	{
		InQueue(q,data[i]);         //将数组的元素按照顺序入队 
	}
	while(q->head!=q->tail)          //访问队列的元素 
	{
		printf("%d ",OutQueue(q).num);
	}

}

关于队列和栈,在C++标准库中均有对应的库文件进行相关操作,如果要用到可以直接调用库文件进行操作即可,非常方便,但是在初学的时候还是尽量可以自己用C语言写出来,知其然,还要知其所以然才能够走的更远。

明天更一下树结构和图结构的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值