常用数据结构
1. 链表
链表可以使用数组实现,也可以使用指针实现。用数组实现的链表的插入、删除操作需要O(N)的时间复杂度,很少使用。
用指针实现的链表,插入删除操作可以O(1)时间完成。
Code
2. 栈
栈是插入删除操作都只能在一个位置上进行的表,该位置是表的末端,叫做顶。栈可以用数组实现,也可以用单链表。
Code
3. 队列
队列也是表,使用队列时插入在一端进行而删除则在另一端进行。使用循环数组实现。当队列为空时,size=0。
Code
4. 二叉查找树
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的节点都连续集中在最左边,这就是完全二叉树。
满二叉树:除最后一层外,每一层上的所有结点都有两个子结点(最后一层上的结点为叶子结点)。也可以这样理解,除叶子结点外的所有结点均有两个子结点。
对于树中的每个结点X,它的左子树中所有关键字的值都小于X的关键字值,而它的右子树中所有关键字值大于X的关键字值。二叉树不一定是完全树,堆才是完全树。
Code
AVL树:一棵AVL树是其每个结点的左子树和右子树的高度最多差1的二叉查找树。
5. 堆
堆有两个性质,即结构性和堆序性。
结构性:堆是一棵被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入。堆用数组实现,数组下标为0的元素不存数据,从下标1开始。对于数组任一位置i上的元素,其左儿子在位置2i上,右儿子在左儿子后的单元[2i+1]中,它的父亲则在位置[i/2]
堆序性:在每一个堆中,对于每个节点X,X的父亲中的关键字小于(或等于)X中的关键字,根节点除外。这个是对于小顶堆。
代码
堆结构定义
struct HeapStruct
{
int Capacity;
int size;
ElementType *Elements;
};
堆常用操作
void Insert(ElementType X,HeapStruct* H);//涉及到上滤
{
int i;
if(!IsFull(H))
{
Error("PriorityQueue is full.");
return;
}
for(i=++H->size;H->Elements[i/2]>X;i/=2)
H->Elements[i]=H->Elements[i/2];
H->Elements[i]=X;
}
ElementType DeleteMin(HeapStruct* H);//复杂,暂时不掌握了
ElementType FindMin(HeapStruct* H);
int IsFull(HeapStruct* H);
int IsEmpty(HeapStruct* H);
struct HeapStruct
{
int Capacity;
int size;
ElementType *Elements;
};
堆常用操作
void Insert(ElementType X,HeapStruct* H);//涉及到上滤
{
int i;
if(!IsFull(H))
{
Error("PriorityQueue is full.");
return;
}
for(i=++H->size;H->Elements[i/2]>X;i/=2)
H->Elements[i]=H->Elements[i/2];
H->Elements[i]=X;
}
ElementType DeleteMin(HeapStruct* H);//复杂,暂时不掌握了
ElementType FindMin(HeapStruct* H);
int IsFull(HeapStruct* H);
int IsEmpty(HeapStruct* H);