1、常用数据结构一线性队列这里的线性结构实际上指的就是连续内存的意思,只不过使用“线性”这个词显得比较专业而已。前面一篇博客介绍了现象结构的处理方法,那么在这个基础之上我们是不是添加一些属性形成一种新的数据结构类型呢?答案是肯定的,队列便是其中的一种。 队列的性质很简单: (1)队列有头部和尾部 (2)队列从尾部压入数据 (3)队列从头部弹出数据 那么连续内存下的队列是怎么实现的呢?a)设计队列数据结构cppview plaincopy1.typedefstruct_QUEUE_NODE2.3.int*pData;4.intlength;5.inthead;6.inttail;7.intcount
2、;8.QUEUE_NODE;b)申请队列内存cppview plaincopy1.QUEUE_NODE*alloca_queue(intnumber)2.3.QUEUE_NODE*pQueueNode;4.if(0=number)5.returnNULL;6.7.pQueueNode=(QUEUE_NODE*)malloc(sizeof(QUEUE_NODE);8.assert(NULL!=pQueueNode);9.memset(pQueueNode,0,sizeof(QUEUE_NODE);10.11.pQueueNode-pData=(int*)malloc(sizeof(int)*nu
3、mber);12.if(NULL=pQueueNode-pData)13.free(pQueueNode);14.returnNULL;15.16.17.pQueueNode-length=number;18.returnpQueueNode;19.c)释放队列内存cppview plaincopy1.STATUSdelete_queue(constQUEUE_NODE*pQueueNode)2.3.if(NULL=pQueueNode)4.returnFALSE;5.6.assert(NULL!=pQueueNode-pData);7.8.free(pQueueNode-pData);9.f
4、ree(void*)pQueueNode);10.returnTRUE;11.d)把数据压入队列cppview plaincopy1.STATUSinsert_queue(QUEUE_NODE*pQueueNode,intvalue)2.3.if(NULL=pQueueNode)4.returnFALSE;5.6.if(pQueueNode-length=pQueueNode-count)7.returnFALSE;8.9.pQueueNode-tail=(pQueueNode-tail+1)%pQueueNode-length;10.pQueueNode-pDatapQueueNode-ta
5、il=value;11.pQueueNode-count+;12.returnTRUE;13.e)把数据弹出队列cppview plaincopy1.STATUSget_queue_data(QUEUE_NODE*pQueueNode,int*value)2.3.if(NULL=pQueueNode|NULL=value)4.returnFALSE;5.6.if(0=pQueueNode-count)7.returnFALSE;8.9.*value=pQueueNode-pDatapQueueNode-head;10.pQueueNode-pDatapQueueNode-head=0;11.p
6、QueueNode-count-;12.pQueueNode-head=(pQueueNode-head+1)%pQueueNode-length;13.returnTRUE;14.f)统计当前队列中有多少数据cppview plaincopy1.intget_total_number(constQUEUE_NODE*pQueueNode)2.3.if(NULL=pQueueNode)4.return0;5.6.returnpQueueNode-count;7.g)查看队列中初始化的时候总长度是多少cppview plaincopy1.intget_total_number(constQUEU
7、E_NODE*pQueueNode)2.3.if(NULL=pQueueNode)4.return0;5.6.returnpQueueNode-length;7.二线性堆栈前面我们讲到了队列,今天我们接着讨论另外一种数据结构:堆栈。堆栈几乎是程序设计的命脉,没有堆栈就没有函数调用,当然也就没有软件设计。那么堆栈有什么特殊的属性呢?其实,堆栈的属性主要表现在下面两个方面: (1)堆栈的数据是先入后出 (2)堆栈的长度取决于栈顶的高度 那么,作为连续内存类型的堆栈应该怎么设计呢?大家可以自己先试一下:(1)设计堆栈节点cppview plaincopy1.typedefstruct_STACK_N
8、ODE2.3.int*pData;4.intlength;5.inttop;6.STACK_NODE;(2)创建堆栈cppview plaincopy1.STACK_NODE*alloca_stack(intnumber)2.3.STACK_NODE*pStackNode=NULL;4.if(0=number)5.returnNULL;6.7.pStackNode=(STACK_NODE*)malloc(sizeof(STACK_NODE);8.assert(NULL!=pStackNode);9.memset(pStackNode,0,sizeof(STACK_NODE);10.11.pSt
9、ackNode-pData=(int*)malloc(sizeof(int)*number);12.if(NULL=pStackNode-pData)13.free(pStackNode);14.returnNULL;15.16.17.memset(pStackNode-pData,0,sizeof(int)*number);18.pStackNode-length=number;19.pStackNode-top=0;20.returnpStackNode;21.(3)释放堆栈cppview plaincopy1.STATUSfree_stack(constSTACK_NODE*pStack
10、Node)2.3.if(NULL=pStackNode)4.returnFALSE;5.6.assert(NULL!=pStackNode-pData);7.8.free(pStackNode-pData);9.free(void*)pStackNode);10.returnTRUE;11.(4)堆栈压入数据cppview plaincopy1.STATUSstack_push(STACK_NODE*pStackNode,intvalue)2.3.if(NULL=pStackNode)4.returnFALSE;5.6.if(pStackNode-length=pStackNode-top)7
11、.returnFALSE;8.9.pStackNode-pDatapStackNode-top+=value;10.returnTRUE;11.(5)堆栈弹出数据cppview plaincopy1.STATUSstack_pop(STACK_NODE*pStackNode,int*value)2.3.if(NULL=pStackNode|NULL=value)4.returnFALSE;5.6.if(0=pStackNode-top)7.returnFALSE;8.9.*value=pStackNode-pData-pStackNode-top;10.returnTRUE;11.(6)统计当
12、前堆栈中包含多少数据cppview plaincopy1.intcount_stack_number(constSTACK_NODE*pStackNode)2.3.returnpStackNode-top;4. 建议: 堆栈是函数调用的基础,是递归调用的基础,是很多问题的根源,建议朋友们平时有时间好好练习一下。三单向链表有的时候,处于内存中的数据并不是连续的。那么这时候,我们就需要在数据结构中添加一个属性,这个属性会记录下面一个数据的地址。有了这个地址之后,所有的数据就像一条链子一样串起来了,那么这个地址属性就起到了穿线连结的作用。 相比较普通的线性结构,链表结构的优势是什么呢?我们可以总结一
13、下: (1)单个节点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的大小 (2)节点的删除非常方便,不需要像线性结构那样移动剩下的数据 (3)节点的访问方便,可以通过循环或者递归的方法访问到任意数据,但是平均的访问效率低于线性表 那么在实际应用中,链表是怎么设计的呢?我们可以以int数据类型作为基础,设计一个简单的int链表: (1)设计链表的数据结构cppview plaincopy1.typedefstruct_LINK_NODE2.3.intdata;4.struct_LINK_NODE*next;5.LINK_NODE; (2)创建链表cppview plaincopy1.
14、LINK_NODE*alloca_node(intvalue)2.3.LINK_NODE*pLinkNode=NULL;4.pLinkNode=(LINK_NODE*)malloc(sizeof(LINK_NODE);5.6.pLinkNode-data=value;7.pLinkNode-next=NULL;8.returnpLinkNode;9. (3)删除链表cppview plaincopy1.voiddelete_node(LINK_NODE*pNode)2.3.LINK_NODE*pNext;4.if(NULL=pNode|NULL=*pNode)5.return;6.7.pNex
15、t=&(*pNode)-next;8.free(*pNode);9.delete_node(pNext);10. (4)链表插入数据cppview plaincopy1.STATUS_add_data(LINK_NODE*pNode,LINK_NODE*pDataNode)2.3.if(NULL=*pNode)4.*pNode=pDataNode;5.returnTRUE;6.7.8.return_add_data(&(*pNode)-next,pDataNode);9.10.11.STATUSadd_data(constLINK_NODE*pNode,intvalue)12.13.LINK_
16、NODE*pDataNode;14.if(NULL=*pNode)15.returnFALSE;16.17.pDataNode=alloca_node(value);18.assert(NULL!=pDataNode);19.return_add_data(LINK_NODE*)pNode,pDataNode);20. (5)删除数据cppview plaincopy1.STATUS_delete_data(LINK_NODE*pNode,intvalue)2.3.LINK_NODE*pLinkNode;4.if(NULL=(*pNode)-next)5.returnFALSE;6.7.pLi
17、nkNode=(*pNode)-next;8.if(value=pLinkNode-data)9.(*pNode)-next=pLinkNode-next;10.free(pLinkNode);11.returnTRUE;12.else13.return_delete_data(&(*pNode)-next,value);14.15.16.17.STATUSdelete_data(LINK_NODE*pNode,intvalue)18.19.LINK_NODE*pLinkNode;20.if(NULL=pNode|NULL=*pNode)21.returnFALSE;22.23.if(valu
18、e=(*pNode)-data)24.pLinkNode=*pNode;25.*pNode=pLinkNode-next;26.free(pLinkNode);27.returnTRUE;28.29.30.return_delete_data(pNode,value);31. (6)查找数据cppview plaincopy1.LINK_NODE*find_data(constLINK_NODE*pLinkNode,intvalue)2.3.if(NULL=pLinkNode)4.returnNULL;5.6.if(value=pLinkNode-data)7.return(LINK_NODE
19、*)pLinkNode;8.9.returnfind_data(pLinkNode-next,value);10. (7)打印数据cppview plaincopy1.voidprint_node(constLINK_NODE*pLinkNode)2.3.if(pLinkNode)4.printf(%dn,pLinkNode-data);5.print_node(pLinkNode-next);6.7.(8)统计数据cppview plaincopy1.intcount_node(constLINK_NODE*pLinkNode)2.3.if(NULL=pLinkNode)4.return0;
20、5.6.return1+count_node(pLinkNode-next);7.四双向链表前面的博客我们介绍了单向链表。那么我们今天介绍的双向链表,顾名思义,就是数据本身具备了左边和右边的双向指针。双向链表相比较单向链表,主要有下面几个特点: (1)在数据结构中具有双向指针 (2)插入数据的时候需要考虑前后的方向的操作 (3)同样,删除数据的是有也需要考虑前后方向的操作 那么,一个非循环的双向链表操作应该是怎么样的呢?我们可以自己尝试一下: (1)定义双向链表的基本结构cppview plaincopy1.typedefstruct_DOUBLE_LINK_NODE2.3.intdata;4
21、.struct_DOUBLE_LINK_NODE*prev;5.struct_DOUBLE_LINK_NODE*next;6.DOUBLE_LINK_NODE; (2)创建双向链表节点cppview plaincopy1.DOUBLE_LINK_NODE*create_double_link_node(intvalue)2.3.DOUBLE_LINK_NODE*pDLinkNode=NULL;4.pDLinkNode=(DOUBLE_LINK_NODE*)malloc(sizeof(DOUBLE_LINK_NODE);5.assert(NULL!=pDLinkNode);6.7.memset(
22、pDLinkNode,0,sizeof(DOUBLE_LINK_NODE);8.pDLinkNode-data=value;9.returnpDLinkNode;10. (3)删除双向链表cppview plaincopy1.voiddelete_all_double_link_node(DOUBLE_LINK_NODE*pDLinkNode)2.3.DOUBLE_LINK_NODE*pNode;4.if(NULL=*pDLinkNode)5.return;6.7.pNode=*pDLinkNode;8.*pDLinkNode=pNode-next;9.free(pNode);10.delet
23、e_all_double_link_node(pDLinkNode);11. (4)在双向链表中查找数据cppview plaincopy1.DOUBLE_LINK_NODE*find_data_in_double_link(constDOUBLE_LINK_NODE*pDLinkNode,intdata)2.3.DOUBLE_LINK_NODE*pNode=NULL;4.if(NULL=pDLinkNode)5.returnNULL;6.7.pNode=(DOUBLE_LINK_NODE*)pDLinkNode;8.while(NULL!=pNode)9.if(data=pNode-data)10.returnpNode;11.pNode=pNode-next;12.13.14.returnNULL;15.
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1