数据结构->栈和队列学习笔记

栈和队列


前言

前面一些天学了栈和队列,想反过头来复习复习,加深下印象,有什么不对的还望指正。


一、栈

1.栈的概念

栈(Stack):是一种特殊的线性表,它是限定仅在 表尾 \color{red}{表尾} 表尾进行插入和删除操作的线性表。栈又称为 后进先出 \color{red}{后进先出} 后进先出的线性表。我们把 允许插入和删除的一端称为栈顶 \color{red}{允许插入和删除的一端称为栈顶} 允许插入和删除的一端称为栈顶,把另一端称为栈底,不含任何元素的栈称为空栈,栈又称为后进先出的线性表
在这里插入图片描述
压栈:栈的插入操作叫做进栈/压栈/入栈, 入数据在栈顶 \color{red}{入数据在栈顶} 入数据在栈顶
出栈:栈的删除(取出)操作叫做出栈, 出数据也在栈顶 \color{red}{出数据也在栈顶} 出数据也在栈顶

2.栈的主要实现函数

  • void StackInit(ST* ps):栈的初始化

    • void StackDestroy(ST* ps):栈的销毁

      • void StackPush(ST* ps, STDataType x):入栈

        • void StackPop(ST* ps):每次调用删除栈内的一个数据

          • STDataType StackTop(ST* ps):出栈,即取出一个数据,但是不负责删除数据

            • int StackSize(ST* ps):求栈的数据个数

              • bool StackEmpty(ST* ps):判断栈是不是空栈,若是,则返回true,若否,则返回false

                3.栈的实现方式

                栈主要用 数组或者链表 \color{red}{数组或者链表} 数组或者链表来实现,相比于链表来说,数组栈(顺序栈)优势更大
                原因:
                数组栈尾插尾删和链表头插头删效率都高,但是数组栈的缓存利用率更高,虽然有时可能存在一点空间浪费,但是整体而言更优,并且链表每次插入还得消耗一定的指针存储。
                而链表栈的话
                有两种实现方式:

                • 单链表:以头为栈顶,尾为栈底,进行头插头删(反过来的话,需要找前一个数据,效率低)

                    • 双链表:以尾为栈顶,头为栈底直接尾来尾插尾删

                  下面的代码我使用数组(顺序表)来实现栈

                  4.栈的代码实现

                  (1)栈的基本结构

                  typedef int STDataType;
                  typedef struct Stack
                  {
                  	STDataType* a;
                  	int top;//当前数据个数
                  	int capacity;
                  }ST;
                  
                  

                  (2)栈的初始化

                  在这里插入图片描述

                  这个图片的初始化top给的是-1,因此当栈中有数据时它的 t o p 指向的是当前位置 \color{red}{top指向的是当前位置} top指向的是当前位置,而top=0的话,指向的位置则是 当前位置的下一个位置 \color{red}{当前位置的下一个位置} 当前位置的下一个位置

                  void StackInit(ST* ps)
                  {
                  	assert(ps);
                  	ps->a = NULL;
                  	ps->top = 0;//top给0,指向栈顶数据的下一个;top=-1,指向栈顶数据(要先加1,再赋值)
                  	ps->capacity = 0;//栈的容量
                  }
                  

                  (3)栈的销毁

                  void StackDestroy(ST* ps)
                  {
                  	assert(ps);
                  	free(ps->a);
                  	ps->a = NULL;
                  	ps->capacity = 0;
                  	ps->top = 0;
                  }
                  

                  (4)入栈

                  void StackPush(ST* ps, STDataType x)//入栈
                  {
                  	assert(ps);
                  	if (ps->top == ps->capacity)//相等有两个原因1.栈为空 2.栈满了
                  	{
                  	    //先判断栈是满还是空,然后一般开辟两倍的空间
                  		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
                  		STDataType* tmp = realloc(ps->a, sizeof(STDataType)*newcapacity);
                  		if (tmp == NULL)
                  		{
                  			printf("开辟失败\n");
                  			exit(-1);
                  		}
                  		ps->capacity = newcapacity;//把开好的给给它
                  		ps->a = tmp;
                  	}
                  	ps->a[ps->top] = x;//入栈
                  	ps->top++;//往后走一步
                  }
                  

                  (5)栈中数据的删除

                  删除数据就是让它的下标访问不到,下次入栈又可以直接覆盖,不会造成影响
                  但是要注意的是当栈为空时,就不能够删了。

                  void StackPop(ST* ps)//删除
                  {
                  	assert(ps);
                  	assert(!StackEmpty(ps));//防止一直删,删过头了
                  	ps->top--;
                  }
                  

                  (6)出栈

                  只出数据,不负责删除

                  STDataType StackTop(ST* ps)//出栈
                  {
                  	assert(ps);
                  	assert(!StackEmpty(ps));//防止都为空了,还在调用;assert为假,就会报错
                  	return ps->a[ps->top-1];//初始化是top=0,所以top此时是下一个位置,-1才是最后的数据下标
                  	//只负责出栈,不负责删除
                  }
                  

                  (7)求栈的个数

                  int StackSize(ST* ps)//里面的数据个数
                  {
                  	assert(ps);
                  	return ps->top;
                  }
                  

                  (8)判断是否为空栈

                  返回的方法很巧妙

                  bool StackEmpty(ST* ps)
                  {
                  	assert(ps);
                  	return ps->top == 0;//=0,为真,返回true,不为0,为假
                  }
                  

                  5.完整代码

                  (1)Stack.h

                  #include<stdio.h>
                  #include<stdlib.h>
                  #include<assert.h>
                  #include<stdbool.h>
                  typedef int STDataType;
                  typedef struct Stack
                  {
                  	STDataType* a;
                  	int top;
                  	int capacity;
                  }ST;
                  void StackInit(ST* ps);
                  void StackDestroy(ST* ps);
                  void StackPush(ST* ps, STDataType x);
                  void StackPop(ST* ps);
                  STDataType StackTop(ST* ps);
                  int StackSize(ST* ps);
                  bool StackEmpty(ST* ps);
                  

                  (2)Stack.c

                  #include"Stack.h"
                  void test1()
                  {
                  	ST st;
                  	StackInit(&st);
                  	StackPush(&st, 1);
                  	StackPush(&st, 2);
                  	StackPush(&st, 3);
                  	StackPush(&st, 4);
                  	printf("%d ", StackTop(&st));
                  	StackPop(&st);
                  	printf("%d ", StackTop(&st));
                  	StackPop(&st);
                  	
                  	StackPush(&st, 5);
                  	StackPush(&st, 6);
                  	while (!StackEmpty(&st))
                  	{
                  		printf("%d ", StackTop(&st));
                  		StackPop(&st);
                  	}
                  	StackDestroy(&st);//每次
                  }
                  
                  int main()
                  {
                  	test1();
                  	return 0;
                  }
                  

                  (3)Stack1.c

                  #include"Stack.h"
                  void StackInit(ST* ps)
                  {
                  	assert(ps);
                  	ps->a = NULL;
                  	ps->top = 0;//top给0,指向栈顶数据的下一个,top=-1,指向栈顶数据(要先加1)
                  	ps->capacity = 0;
                  }
                  
                  void StackPush(ST* ps, STDataType x)//入栈
                  {
                  	assert(ps);
                  	if (ps->top == ps->capacity)
                  	{
                  		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
                  		STDataType* tmp = realloc(ps->a, sizeof(STDataType)*newcapacity);
                  		if (tmp == NULL)
                  		{
                  			printf("开辟失败\n");
                  			exit(-1);
                  		}
                  		ps->capacity = newcapacity;
                  		ps->a = tmp;
                  	}
                  	ps->a[ps->top] = x;
                  	ps->top++;
                  }
                  	
                  void StackDestroy(ST* ps)
                  {
                  	assert(ps);
                  	free(ps->a);
                  	ps->a = NULL;
                  	ps->capacity = 0;
                  	ps->top = 0;
                  }
                  void StackPop(ST* ps)//删除
                  {
                  	assert(ps);
                  	assert(!StackEmpty(ps));//防止一直删,删过头了
                  	ps->top--;
                  }
                  STDataType StackTop(ST* ps)//出栈
                  {
                  	assert(ps);
                  	assert(!StackEmpty(ps));//防止都为空了,还在调用;assert为假,就会报错
                  	return ps->a[ps->top-1];//初始话是top=0,所以top此时是下一个位置,-1才是最后的数据
                  	//只负责出栈,不负责删除
                  }
                  bool StackEmpty(ST* ps)
                  {
                  	assert(ps);
                  	return ps->top == 0;//=0,为真,返回true,不为0,为假
                  }
                  int StackSize(ST* ps)//里面的数据个数
                  {
                  	assert(ps);
                  	return ps->top;
                  }
                  

                  6.栈的(递归)应用

                  栈的可以用来实现递归
                  每递归一层,就会在栈(操作系统中的栈)中建立栈帧,递归次数多了,就会导致栈帧深度太深,栈空间不够,可能会溢出
                  对于递归改非递归:1.简单的用循环 2.复杂的借助栈来实现
                  像一般的斐波那契和阶乘使用循环就能解决,之前在学快排时,学习过快排改非递归的实现,我在这里就简单介绍一下吧:

                  快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,以第一个为关键字和其他数进行比较分成一边比它小,一边比它大,之后再分别对这两部分记录继续进行排序,直到分解到只剩下左边一个右边一个,这时达到整个序列有序的目的。
                  栈的使用和递归相似,我们将边界下标入栈,栈是先进后出,如果我们要先排左边的话,就得先入右边的下标,我们每入一次栈就出一次栈,然后挖坑排序,重复操作,直到分解到左右边界相等,这时说明已经到底了,不用再分了,当栈最终为空时,排序就排好了

                  这里我只是浅显地说几句,主要还得看各位下去后仔细研究。

                  void QuickSortNonR(int*a,int n)
                  {
                  	ST st;
                  	StackInit(&st);
                  	StackPush(&st, n - 1);//先进后出
                  	StackPush(&st, 0);
                  	while (!StackEmpty(&st))
                  	{
                  		int left = StackTop(&st);
                  		StackPop(&st);
                  		int right = StackTop(&st);
                  		StackPop(&st);
                  		int keyindex = partsort(a, left, right);//挖坑法得出中间的下标
                  		//[left,keyindex-1] keyindex [keyindex+1,right]
                  		//当两边的边际相等时,说明已经递归到最低部了,上去一层,左右区间都只有一个数
                  		//即都是有序的了
                  		if (keyindex + 1 < right)//注意入栈顺序,先出左,那就要先入右
                  		{
                  			StackPush(&st, right);
                  			StackPush(&st, keyindex + 1);
                  		}
                  		if (left < keyindex - 1)//
                  		{
                  			StackPush(&st, keyindex - 1);
                  			StackPush(&st,left );
                  		}
                  	}
                  	StackDestroy(&st);
                  }
                  

                  挖坑法:每次以左第一个为关键字,左边有坑,到右边找小的,找到后放到坑里,坑更新到右边,继续到左边找大的,当两边边界相等时,这时左右区间分成了一大一小的区间。

                  int partsort(int* a, int left, int right)//将挖坑法提了出来
                  {
                  	int index = GetMidIndex(a, left, right);
                  	Swap(&a[left], &a[index]);
                  	int begin = left, end = right;
                  	int pivot = begin, key = a[begin];
                  	while (begin < end)
                  	{
                  		//右边找小,放到左边的坑
                  		while (begin < end && a[end] >= key)
                  		{
                  			end--;
                  		}
                  		//填坑,更新坑
                  		a[pivot] = a[end];
                  		pivot = end;
                  		//左边找大,放到右边
                  		while (begin < end && a[begin] <= key)
                  		{
                  			begin++;
                  		}
                  		a[pivot] = a[begin];
                  		pivot = begin;
                  	}
                  	a[pivot] = key;//循环出来时,那个坑就是放key
                  	return pivot;
                  }
                  
                  
                  
                  

                  二、队列

                  1.队列的定义

                  队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点。(这里和栈是相反的)

                  • 入队列:进行插入操作的一端称为队尾

                    • 出队列:进行删除操作的一端称为队头

                      在这里插入图片描述

                      实际中我们有时还会使用一种队列叫循环队列,长这样:
                      在这里插入图片描述
                      在这里插入图片描述
                      但是由于这种的队列我没怎么学过,
                      还有看其他的资料还有双端队列,这个我也没学,因此在这里我也是能力有限,无法帮到大家了。

                      2.队列的实现

                      队列也可以用数组和链表的结构实现,使用链表的结构实现更优一些
                      如果使用数组的话,出入数据时,需要挪动数据,因此效率上比较低,而链表就蛮适合的,具体使用双链表还是单链表就看自己的了,我使用的是单链表。
                      在这里插入图片描述

                      • 入队列从队尾入,直接让尾的next指向新开的节点,尾指针rear往后走走

                        • 出队列从队头出,取出数据后,断开front,让它往后移,成为新的头

                          3.队列的基本结构

                          typedef int QDataType;
                          
                          typedef struct QueueNode
                          {
                          	QDataType data;
                          	struct QueueNode* next;
                          }QueueNode;
                          
                          typedef struct Queue
                          {
                          	QueueNode* head;
                          	QueueNode* tail;
                          }Queue;
                          

                          4.队列的主要实现函数

                          • void QueueInit(Queue* pq):初始化队列

                            • void QueueDestroy(Queue* pq):销毁队列

                              • void QueuePush(Queue* pq, QDataType x):入队列

                                • void QueuePop(Queue* pq):从队头删数据

                                  • QDataType QueueFront(Queue* pq):取出队头的数据

                                    • QDataType QueueBack(Queue* pq):取队尾的数据

                                      • int QueueSize(Queue* pq):队列的数据个数

                                        • bool QueueEmpty(Queue* pq):判断队列是否为空

                                          5.玩转队列代码

                                          (1)队列初始化

                                          void QueueInit(Queue* pq)
                                          {
                                          	assert(pq);
                                          	pq->head = NULL;
                                          	pq->tail = NULL;
                                          }
                                          

                                          (2)(队列的销毁)

                                          销毁数据得从头到尾一个一个释放,直到cur为空,最后置空指针

                                          void QueueDestroy(Queue* pq)
                                          {
                                          	assert(pq);
                                          	QueueNode* cur = pq->head;
                                          	while (cur)
                                          	{
                                          		QueueNode* next = cur->next;
                                          		free(cur);
                                          		cur = next;
                                          	}
                                          	pq->head = NULL;
                                          	pq->tail = NULL;
                                          }
                                          
                                          

                                          (3)队列的插入函数

                                          void QueuePush(Queue* pq, QDataType x)//从队尾插入
                                          {
                                          	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
                                          	if (newnode == NULL)
                                          	{
                                          		printf("开辟新节点失败");
                                          		exit(-1);
                                          	}
                                          	newnode->data = x;
                                          	newnode->next = NULL;
                                          //以上是开辟新节点并赋值x
                                          	if (pq->head == NULL)//不要忘记
                                          	{
                                          		pq->head = pq->tail = newnode;
                                          	}
                                          	else
                                          	{
                                          		pq->tail->next = newnode;//链接新节点
                                          		pq->tail = newnode;
                                          	}
                                          }
                                          

                                          (4)队列的删除函数

                                          这个函数还是有很多细节要我们注意的
                                          队列不能为空 \color{red}{队列不能为空} 队列不能为空,当删除完一个数后 还得判断是不是删完了 \color{red}{还得判断是不是删完了} 还得判断是不是删完了,删完了还要 将最后一个指针置空 \color{red}{将最后一个指针置空} 将最后一个指针置空
                                          细节很多

                                          void QueuePop(Queue* pq)//只能从队头开始删
                                          {
                                          	assert(pq);
                                          	assert(!QueueEmpty(pq));
                                          	QueueNode* next = pq->head->next;//这里要注意的是pq->head不能为空
                                          	//如果为空,还去->next,那么程序就崩溃了,所以上面加了断言
                                          	free(pq->head);
                                          	pq->head = next;
                                          	if (pq->head == NULL)//说明队列已经删完了,此时pq->tail被free,但是为野指针
                                          	{
                                          		pq->tail = NULL;//应当置空
                                          	}
                                          }
                                          

                                          (5)取队头数据

                                          QDataType QueueFront(Queue* pq)//取头的数据
                                          {
                                          	assert(pq);
                                          	assert(!QueueEmpty(pq));//!!!
                                          	return pq->head->data;//同样注意pq->head为不为空
                                          }
                                          

                                          (6)取队尾数据

                                          QDataType QueueBack(Queue* pq)//取队尾的数据
                                          {
                                          	assert(pq);
                                          	assert(!QueueEmpty(pq));//
                                          	return pq->tail->data;
                                          }
                                          

                                          (7)求队列的数据个数

                                          int QueueSize(Queue* pq)//采用计数的方法来
                                          {
                                          	assert(pq);
                                          	int n = 0;
                                          	QueueNode* cur = pq->head;
                                          	while (cur)
                                          	{
                                          		n++;
                                          		cur = cur->next;
                                          	}
                                          	return n;
                                          }
                                          

                                          (8)判断队列为不为空

                                          bool QueueEmpty(Queue* pq)
                                          {
                                          	assert(pq);
                                          	return pq->head == NULL;//
                                          }
                                          

                                          6.完整代码

                                          (1)头文件Queue.h

                                          #include<stdio.h>
                                          #include<stdlib.h>
                                          #include<assert.h>
                                          #include<stdbool.h>
                                          typedef int QDataType;
                                          
                                          typedef struct QueueNode
                                          {
                                          	QDataType data;
                                          	struct QueueNode* next;
                                          }QueueNode;
                                          
                                          typedef struct Queue
                                          {
                                          	QueueNode* head;
                                          	QueueNode* tail;
                                          }Queue;
                                          void QueueInit(Queue* pq);
                                          void QueueDestroy(Queue* pq);
                                          void QueuePush(Queue* pq, QDataType x);
                                          void QueuePop(Queue* pq);
                                          QDataType QueueFront(Queue* pq);
                                          QDataType QueueBack(Queue* pq);
                                          int QueueSize(Queue* pq);
                                          bool QueueEmpty(Queue* pq);
                                          
                                          

                                          (2)Queue.c

                                          #include "Queue.h"
                                          //队列先进先出
                                          //队头出,队尾入
                                          //删除-》出队列
                                          //插入-》入队列
                                          void test1()
                                          {
                                          	Queue q;
                                          	QueueInit(&q);
                                          	QueuePush(&q, 1);
                                          	QueuePush(&q, 2);
                                          	QueuePush(&q, 3);
                                          	
                                          	printf("%d\n", QueueFront(&q));
                                          	QueuePop(&q);
                                          	QueuePush(&q, 4);
                                          	//printf("%d\n", QueueBack(&q));
                                          	while (!QueueEmpty(&q))
                                          	{
                                          		printf("%d ", QueueFront(&q));
                                          		QueuePop(&q);
                                          	}
                                          	QueueDestroy(&q);
                                          }
                                          int main()
                                          {
                                          	test1();
                                          	
                                          	return 0;
                                          }
                                          
                                          

                                          (3)Queue1.c(主要函数实现)

                                          #include "Queue.h"
                                          void QueueInit(Queue* pq)
                                          {
                                          	assert(pq);
                                          	pq->head = NULL;
                                          	pq->tail = NULL;
                                          }
                                          void QueueDestroy(Queue* pq)
                                          {
                                          	assert(pq);
                                          	QueueNode* cur = pq->head;
                                          	while (cur)
                                          	{
                                          		QueueNode* next = cur->next;
                                          		free(cur);
                                          		cur = next;
                                          	}
                                          	pq->head = NULL;
                                          	pq->tail = NULL;
                                          }
                                          
                                          void QueuePush(Queue* pq, QDataType x)//从队尾插入
                                          {
                                          	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
                                          	if (newnode == NULL)
                                          	{
                                          		printf("开辟新节点失败");
                                          		exit(-1);
                                          	}
                                          	newnode->data = x;
                                          	newnode->next = NULL;
                                          
                                          	if (pq->head == NULL)//不要忘记
                                          	{
                                          		pq->head = pq->tail = newnode;
                                          	}
                                          	else
                                          	{
                                          		pq->tail->next = newnode;
                                          		pq->tail = newnode;
                                          	}
                                          }
                                          void QueuePop(Queue* pq)//只能从队头开始删
                                          {
                                          	assert(pq);
                                          	assert(!QueueEmpty(pq));
                                          	QueueNode* next = pq->head->next;
                                          	free(pq->head);
                                          	pq->head = next;
                                          	if (pq->head == NULL)//说明队列已经删完了,此时pq->tail被free,但是为野指针
                                          	{
                                          		pq->tail = NULL;//应当置空
                                          	}
                                          }
                                          
                                          QDataType QueueFront(Queue* pq)//取头的数据
                                          {
                                          	assert(pq);
                                          	assert(!QueueEmpty(pq));//!!!
                                          	return pq->head->data;
                                          }
                                          QDataType QueueBack(Queue* pq)//取队尾的数据,仅仅是类似打印
                                          {
                                          	assert(pq);
                                          	assert(!QueueEmpty(pq));//
                                          	return pq->tail->data;
                                          }
                                          int QueueSize(Queue* pq)//采用计数的方法来
                                          {
                                          	assert(pq);
                                          	int n = 0;
                                          	QueueNode* cur = pq->head;
                                          	while (cur)
                                          	{
                                          		n++;
                                          		cur = cur->next;
                                          	}
                                          	return n;
                                          }
                                          bool QueueEmpty(Queue* pq)
                                          {
                                          	assert(pq);
                                          	return pq->head == NULL;//
                                          }
                                          
                                          

                                          总结及相关题目小试

                                          栈和队列两种结构相反,但是主要的实现函数差不多都是相同的,另外这里还有两道题
                                          用队列实现栈
                                          用栈实现队列
                                          大家可以去试试,这样更好的理解这两种结构。好了今天的讲解也就结束了,希望对大家有帮助。

                                          • 3
                                            点赞
                                          • 0
                                            收藏
                                            觉得还不错? 一键收藏
                                          • 3
                                            评论
                                          数据结构学习资料分享 内容概览: 本次分享包涵了大学计算机相关专业必学的“数据结构”课程的一系列学习资料。主要包括: 算法代码:我们提供了多种数据结构的实现代码,包括数组、链表、栈、队列、树、图等。这些代码不仅能帮助你理解数据结构的基本概念,而且能让你明白如何在实际情况中应用这些数据结构笔记:详细且系统的笔记,涵盖了数据结构的各个方面,从基础概念到复杂的数据结构如堆、B树等。这些笔记有助于你系统地复习和学习数据结构。 相关书籍推荐:为了更深入地理解数据结构,我们推荐了几本经典的教材和参考书籍。这些书籍将帮助你建立完整的数据结构知识体系。 适用人群: 这份学习资料适用于所有大学计算机相关专业的学生,无论你是初学者还是已经有一定的数据结构基础。同时,对于对数据结构感兴趣的非专业人士,这份资料也是一个很好的起点。 使用建议: 结合理论和实践:在学习的过程中,请结合算法代码和理论知识。尝试自己编写代码实现数据结构,并在遇到问题时参考提供的代码。 由浅入深:建议先从基础的数据结构开始学习,如数组和链表,然后再学习更复杂的数据结构如树和图。 多做练习:数据结构是实践性很强的学科。通过多做练习,你可以更好地理解数据结构的基本概念和原理,并提高编程能力。
                                          数据结构学习资料分享 内容概览: 本次分享包涵了大学计算机相关专业必学的“数据结构”课程的一系列学习资料。主要包括: 算法代码:我们提供了多种数据结构的实现代码,包括数组、链表、栈、队列、树、图等。这些代码不仅能帮助你理解数据结构的基本概念,而且能让你明白如何在实际情况中应用这些数据结构笔记:详细且系统的笔记,涵盖了数据结构的各个方面,从基础概念到复杂的数据结构如堆、B树等。这些笔记有助于你系统地复习和学习数据结构。 相关书籍推荐:为了更深入地理解数据结构,我们推荐了几本经典的教材和参考书籍。这些书籍将帮助你建立完整的数据结构知识体系。 适用人群: 这份学习资料适用于所有大学计算机相关专业的学生,无论你是初学者还是已经有一定的数据结构基础。同时,对于对数据结构感兴趣的非专业人士,这份资料也是一个很好的起点。 使用建议: 结合理论和实践:在学习的过程中,请结合算法代码和理论知识。尝试自己编写代码实现数据结构,并在遇到问题时参考提供的代码。 由浅入深:建议先从基础的数据结构开始学习,如数组和链表,然后再学习更复杂的数据结构如树和图。 多做练习:数据结构是实践性很强的学科。通过多做练习,你可以更好地理解数据结构的基本概念和原理,并提高编程能力。
                                          数据结构学习资料分享 内容概览: 本次分享包涵了大学计算机相关专业必学的“数据结构”课程的一系列学习资料。主要包括: 算法代码:我们提供了多种数据结构的实现代码,包括数组、链表、栈、队列、树、图等。这些代码不仅能帮助你理解数据结构的基本概念,而且能让你明白如何在实际情况中应用这些数据结构笔记:详细且系统的笔记,涵盖了数据结构的各个方面,从基础概念到复杂的数据结构如堆、B树等。这些笔记有助于你系统地复习和学习数据结构。 相关书籍推荐:为了更深入地理解数据结构,我们推荐了几本经典的教材和参考书籍。这些书籍将帮助你建立完整的数据结构知识体系。 适用人群: 这份学习资料适用于所有大学计算机相关专业的学生,无论你是初学者还是已经有一定的数据结构基础。同时,对于对数据结构感兴趣的非专业人士,这份资料也是一个很好的起点。 使用建议: 结合理论和实践:在学习的过程中,请结合算法代码和理论知识。尝试自己编写代码实现数据结构,并在遇到问题时参考提供的代码。 由浅入深:建议先从基础的数据结构开始学习,如数组和链表,然后再学习更复杂的数据结构如树和图。 多做练习:数据结构是实践性很强的学科。通过多做练习,你可以更好地理解数据结构的基本概念和原理,并提高编程能力。

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

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

                                          请填写红包祝福语或标题

                                          红包个数最小为10个

                                          红包金额最低5元

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

                                          抵扣说明:

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

                                          余额充值