导航菜单
首页 >  考研数据结构该怎么学  > 考研心得:考研数据结构算法大全

考研心得:考研数据结构算法大全

本人考研的算法笔记,包含考研数据结构会涉及到的算法,全部掌握让你考研算法题稳稳拿下!!

一、排序 1.插入排序

算法思想:第i次插入排序:向i-1个有序数列中插入一个元素,使之称为含有i个元素的有序子序列。将当前元素和前驱元素比较,若大于则表示有序,不用改变;否则将该元素插入到前面,并且前面比它大的元素后移。

void InsertSort ( int a[] , int n ){int temp , i , j;for( i = 1 ; i=1 ; d = d/2)//步长变化for( i = d + 1 ; irchild)Q[rear++] = p->rchild;​if (front == tag)//当遍历完当前行最后一个后​{​depth++;//层数增加并更新标记最后结点的tag​tag = rear;​}​}​return depth;}

②递归

int Tree_Depth(BiTree T){​if (T == NULL)​return 0;​int ldepth = Tree_Depth(T->lchild);​int rdepth = Tree_Depth(T->rchild);​if (ldepth > rdepth)​return ldepth+1;​else​return rdepth+1;} 6.求结点所在层数

①非递归(简化)

用5①的非递归,当发现所查结点时输出depth+1(因为这时当前行还没运行完,depth还没有+1)

while (front lchild)Q[rear++] = p->lchild;​if (p->rchild)Q[rear++] = p->rchild;​if (front == tag)//当遍历完当前行最后一个后​{​depth++;//层数增加并更新标记最后结点的tag​tag = rear;​}}

②递归

思想:若当前结点为空则返回0;若找到该结点则返回该结点的层数;遍历左右子树,若左右子树大于0则表示找到了,返回左/右子树的返回值

int Level(BTree T, BTNode* p, int depth){if(!T) return 0;if(T==p) return depth;int L = Level(T->lchild, p, depth+1);if(L>0) return L;//即找到了int R = Level(T->lchild, p, depth+1);if(R>0) return R;//即找到了return -1;//未找到} 7.求树的宽度

①非递归int Width_Depth(BiTree T)(简化)

算法思想:利用5①的非递归遍历,在遍历每一行的时候都计算下一行的个数count=front-rear

int count=1, width=1;//count表示下一行的结点个数,max表示树的宽度(最大count)​while (front lchild)Q[rear++] = p->lchild;​if (p->rchild)Q[rear++] = p->rchild;​if (front == tag)//当遍历完当前行最后一个后​{tag = rear;width= rear - front;//计算当前行的个数​if (width> max)max = width;//更新最大width​}​}​return width;//返回width

②递归

算法思想:开辟一个数组count[二叉树高度],遍历每一个节点,然后根据当前节点所在层次i,则执行count[i]++;最后遍历完求出最大的count即为二叉树宽度

int count[10];int Max = -1;void FindWidth(BiTree T, int k){​if (!T)return;​count[k]++;//k层结点数+1​if (Max lchild, k + 1);//遍历左右子树​FindWidth(T->rchild, k + 1);} 8.交换二叉树所有结点的左右子树

①算法思想:使用层序遍历,但是在每次将左右子树入队时改为右左的顺序入队

②递归:算法思想:先序遍历(中序也可)左右子树,并且每次遍历将左右子树互换

void swap(BiTree T){BiTree q;//左右子树互换​q = T->lchild;​T->lchild = T->rchild;​T->rchild = q;swap(T->lchild);//递归交换左右孩子的左右子树​swap(T->rchild);} 9.求叶子结点个数-递归

算法思想:1.若结点为空则返回0;2.若结点为叶子结点则返回1;3.否则返回左子树和右子树叶子结点的和。递归调用

int Degree0(BiTree T){​if (!T)return 0;​if (T->lchild == NULL && T->rchild == NULL)return 1;//若为叶子结点,返回1​else return Degree0(T->lchild) + Degree0(T->rchild);//否则返回左右子树叶子数相加} 10.求度为2的结点个数-递归

算法思想:1.若结点为空则返回0;2.若结点度为2则返回1+左右子树度为2的结点之和;3.否则返回左子树和右子树叶子结点的和。递归调用

int Degree2(BiTree T){​if (!T)return 0;​if (T->lchild != NULL && T->rchild != NULL)//若度为2,则return 1+ Degree2(T->lchild) + Degree2(T->rchild);//返回左右子树的度为2的结点个数和+1​else return Degree2(T->lchild) + Degree2(T->rchild);//否则当前结点不是度为2,结点数不+1} 11.求度为1的结点个数-递归

算法思想:1.若结点为空则返回0;2.若结点度为2则返回1+左右子树度为2的结点之和;3.否则返回左子树和右子树叶子结点的和。递归调用

int Degree1(BiTree T){​if (!T)return 0;​if (T->lchild != NULL && T->rchild == NULL)​return 1+ Degree1(T->lchild) + Degree1(T->rchild);else if (T->lchild == NULL && T->rchild != NULL)​return 1+ Degree1(T->lchild) + Degree1(T->rchild);​else return Degree1(T->lchild) + Degree1(T->rchild);} 12.找最近公共祖先(求祖先都用后序遍历,因为栈保存的都是其祖先)

算法思想:后序遍历当找到任意一个时保存当前栈中的元素,若两个都找到后退出循环并遍历找公共组先

BTNode* PrintParents_qp(BiTree T, BTNode *x,BTNode *y){​if (!T) return NULL;​BTNode *stack[10], *a[10], *b[10], *p = T, *r = NULL;//初始化栈​int top = -1, pa = 0, pb = 0;​while (top != -1 || p != NULL)//栈非空或树未遍历完​{​if (p)//走到最左边​{​if (p == x)//若找到x,则保存此时的栈​{​for (int i = 0; i rchild&&p->rchild != r)//若右子树并且未遍历​{​stack[++top] = p;//再把结点入栈并退出循环​p = p->rchild;//右子树入栈​}​else//否则直接继续循环​{​r = p;​p = NULL;​}​}​}​//找公共祖先​int i=0;​for(i=0; a[i] == b[i]&&irchild = NULL;​return 1;//返回1,插入成功​}​else if (T->data == key)//若树中存在相同关键字,则插入失败​return 0;​else if (T->data > key)//插入到T的左子树中​return BST_Insert(T->lchild, key);​else//插入到T的右子树中​return BST_Insert(T->rchild, key);} 14.2二叉排序树搜索操作

算法思想:若等于结点的值或结点为空则返回结点;若小于结点的值则搜索左子树;若大于结点的值则搜索右子树

BTNode * BST_Search(BiTree T, int key)//非递归查找算法{​while (T&&T->data != key)//若树非空或不等于结点值​{​if (key data)T = T->lchild;//若小于则向左查找​elseT = T->rchild;//若大于则向右查找​}​return T;} 14.3二叉排序树构造操作

算法思想:通过二叉树的插入算法,将数组中的所有结点都依次插入到二叉排序树中

void Creat_BST(BiTree &T, int str[], int n)//构造二叉树{​T = NULL;//初始时T为空树​int i = 0;​while (i lchild&&T->lchild->data > T->data)return false;​if (T->rchild&&T->rchild->data data)return false;​return Decide(T->lchild) && Decide(T->lchild);} 15.判断是否是平衡二叉树

算法思想:设置二叉树的平衡标记balance,标记返回二叉树T是否为平衡二叉树,若为平衡二叉树则返回1,否则返回0;h为二叉树T的高度。采用后序遍历的递归算法:

①若T为空,则高度为0,balance=1;

②若T为仅有根结点(即叶子结点),则高度为1,balance=1;

③否则,对T的左右子树进行递归操作,返回左右子树的高度和平衡标记,

T的高度为最高的子树的高度+1.

若左右子树的高度差大于1,则balance=0;

若左右子树的高度差小于等于1,*且左右子树都平衡时*,balance=1,否则balance=0.

void Judge_AVL(BiTree T, int &balance, int &h)//加上取地址符//balance返回是否是平衡二叉树,若是则返回1,否则返回0;h是二叉树的高度{​int bl = 0, br = 0, hl = 0, hr = 0;//左右子树的平衡标记和高度​if (!T) //空树,高度为0​{​h = 0;​balance = 1;​}​else if (T->lchild == NULL && T->rchild == NULL)​{//若为根结点,则高度为1​h = 1;​balance = 1;​}​else​{​Judge_AVL(T->lchild, bl, hl);//判断左子树​Judge_AVL(T->rchild, br, hr);//判断右子树​h = (hl > hr ? hl : hr) + 1;​balance = bl&&br;//若左右子树都平衡时,二叉树平衡​else​balance = 0;​}} 五、串 1.存储结构

①定长顺序存储

typedef struct SString selected选定{char ch[Max_Size];//每个分量存储一个字符int length;//串的实际长度}SString;

②堆分配存储

typedef struct HString heap堆{char * ch;//按串长分配存储区,ch指向串的基地址int length;//串的实际长度}HString;

③块链存储(eg大小为1的链表)

typedef struct LString{char data;//按串长分配存储区,ch指向串的基地址struct LString *Next;//指向下一个结点}LString; 2.KMP void get_next(String T, int next[]){​int i = 1, j = 0;//i表示next的位置​next[1] = 0;//初始化第一个值​while (i

相关推荐: