从本章开始,讨论数据结构。
动态集:数据结构讨论集合时,一般集合的元素是可以变化的,可以向集合中添加、删除、修改元素的值。
动态集上的操作:
查找、添加、删除、取最大值、取最小值、前驱、后继。
基本数据结构:
1 栈:后进先出(LIFO)。插入--入栈(PUSH),删除--出栈(POP),查看栈顶元素(TOP)。
2 队列:先进先出(FIFO)。插入--入队(ENQUEUE),删除--出队(DEQUEUE),查看队头、队尾。
3 双端队列:队列两端都可进行插入、删除操作。
4 链表:和数组一样,链表也表现为线性性质,其线性由元素指针表示,而数组线性性质由数组下标表示。
链表的表现方式有:单链表、双链表;已排序、未排序;环形、非环形。
应用与技巧:
Ø 用两个栈实现队列。
Ø 用两个队列实现栈。
Ø 哨兵元素的应用。
Ø 用单链表实现栈。
Ø 用单链表实现队列。
Ø 单链表的反序,O(n)时间,O(1)空间。
Ø 使用一个指针来实现双链表,指针域只有一个指针。节点指针域由前驱和后继指针异或来表示;链表保留链表的头节点和尾节点。
原理:
x^y^y=x^(y^y)=x^0=x(异或操作)。
普通单链表头节点的pre为NULL,因此单指针表示时,head->np=head->pre^head->nex=head->next(由第二个节点,可以知道头节点),即head->next=head->np(由头节点,可以知道第二个节点);从而由头节点可以得到第二个节点,由第二个节点也可以得到头节点。
对任意节点,由
node->np=node->pre^node->next-------1式
可得
node->next=node->np^node->pre-----2式
两边同对node->pre做一次异或。由前一个节点和当前节点可以得到下一个节点。
node->pre=node->np^node->next----3式
两边对node->next做一次异或。由下一个节点和当前节点,可以得到前一个节点。
从而如果往后遍历,则保留前一个节点即可和当前节点异或得到后一个节点;如果往前遍历,则保留后一个节点即可和当前节点异或得到前一个节点,从而完成双向操作。
除了使用异或操作,也可以使用”加减”操作来实现1,2,3式的关系。
当前节点的指针域不为前一个节点和后一个节点指针的异或,而是为前一个节点和后一个节点的相加。相应的1,2,3式为
Node->np=node->pre+node->next
Node->next=node->np-node->pre
Node->pre=node->np-node->next
Ø 数组实现指针
5 树
树、二叉树、无限制树
树的表示方式:二叉树的二叉(双孩子)、三叉(双孩子、父亲)、线索二叉表示法;树的孩子兄弟节点表示法。