闲的没事干

稀疏矩阵 三元组转置

转置详解链接

矩阵转置的实现思路是:不断遍历存储矩阵的三元组表,每次都取出表中 j 列最小的那一个三元组,
互换行标和列标的值,并按次序存储到一个新三元组表中。

栈和队列

十进制转换任意进制

int switch_num(int num,int hex){
    if(num<0)
		num = -num;
    if(num==0)
        return 0;
    stack s; //用栈保存转换过程中后的每一位
    while(num){
        s.push(num % hex);
        num /= hex;
    }
    while(! s.empty()){
        if(s.top() < 10 )
            printf("%c",s.top()+ '0');
        else        //针对 16进制大于10 情况 ,A-10 B-11
            printf("%c",s.top() -10 +'A');
         s.pop();
    }
}

字符串回文判定

int judge( char * str){
    stack s;
    int len =strlen(str);
    for(int i=0;i<len;i++)
        s.push(str[i]);
    for(int i=0;i<len;i++){
        if(s.top() != str[i])
            return 0;
        s.pop();
    }
    return 1;
}

非递归先序中序后序

void Inorder(Tree * t){		//中序
    InitStack(s);
    Tree *p=t;
    while(p || ! IsEmpty(s)){     //栈不空或 p不空时循环
        if(p){                  //一路向左下
            push(s,p);
            p= p->lchild;
        }
        else{
            pop(s,p);
            visit(p);
            p = p->rchild;
        }
    }
}

void PreOrder(Tree *t){			//先序
    InitStack(s);
    Tree * p =t;
    while(p || ! IsEmpty(s)){
        if(p){     
            visit(p);
            push(s,p);
            p=p->lchild;
        }
        else{
            pop(s,p);
            p=p->rchild;
        }
    }
}
// -----------------------------------------------非递归后序遍历
void PostPrder(Tree * t){
    InitStack(s);
    Tree *p =t;
    Tree * temp=NULL;			//辅助 用来判别右子树是否已访问
    while( p || ! IsEmpty(s)){
        if(p){
            push(s,p);
            p=p->lchild;
        }
        else{
            GetTop(s,p);					// 读栈顶节点(非出栈)
            if(p->rchild && p->rchild !=temp){     //右子树存在且右子树未访问
                p= p->rchild;
            }
            else{
                pop(s,p);			//节点弹出
                visit(p->data);		//访问节点
                temp =p;			//记录最近访问节点
                p=NULL;				//访问完,重置p指针
            }
        }
    }
}

层次遍历

void Order(Tree * t){			//层次遍历
    InitQueue(q);
    Tree *p;
    EnQueue(q,t);
    while(! IsEmpty(q)){
        DeQueue(q,p);       //对头元素出队,并赋给p
        visit(p);
        if(p->lchild !=NULL)
            EnQueue(q,p->lchild);
        if(p->rchild != NULL)
            EnQueue(q,p->rchild);
    }
}

寻找祖先

1.顺序结构存储 找两节点最近公共祖先

int test(Tree t,int i,int j){	//一维数组存储
    if(t[i]!='-1' && t[j]!='-1'){
        while(i!=j){
            if(i>j)
                i=i/2;
            else
                j=j/2;
        }
        return t[i];
    }
}

2.链式存储,找单节点所有祖先

typedef struct{
    Tree t;
    int tag;
}stack;
void search(Tree *t,int x){
    stack s[];
    Tree*p=t;
    top=0;
    while( p || top>0){
        while(p && p->data!=x){
            s[++top].t =p;
            s[top].tag=0;
            p=p->lchild;                    //左下遍历
        }
        if(p && p->rchild==x){
            printf("所有祖先结点:");		
            for(int i=1;i<=top;i++)
                printf("%d", s[i].t->data);	//从下往上输出 最近祖先到根节点
            exit(1);        //结束
        }
        while(top!=0 && s[top].tag==1)
            top--;                          //退栈
        if(top!=0){
            s[top].tag=1;					//修改该节点top标记
            p= s[top].t->rchild;           //更新p,并向右下遍历
        }
    }
}

判断是否为二叉排序树

1.顺序存储—递归实现(中序)(完全二叉树 层次遍历理解 下标从开始)

typedef struct{
	int node[max];	//保存二叉树节点值的数组
	int elemnum;	//元素个数
}Tree;
int pre=0;			//全局变量 
bool InOrder(Tree*t,int i){
    if(t->Node[i] == -1)      //空节点符合
        return true;
    if(!InOrder(t,2*i+1))          //递归左子树		(下标1开始 2i)
        return false;               //左子树不符合 返回flase
    if(pre > t->Node[i])      // 如果前驱大于当前节点 不符合
        return false;
      
    pre=t->Node[i];           //更新前驱
    if(!InOrder(t,2*i+2))          //递归右子树		(下标1开始 2i+1)
        return false;
    return true;        
}

2.链式存储—递归

int pre = -1;               //全局变量
bool judge(Tree* root) {// 判断二叉树是否为二叉排序树的递归方法
    if (root == NULL)
        return true;
    if (! judge(root->left)) // 遍历左子树
        return false;
    if (root->data < pre) // 检查当前节点
        return false;    
        
    pre = root->data;     //更新前驱
    return judge(root->right);    // 遍历右子树
}

判断两二叉树是否相似

int  same(Tree* a,Tree* b){
    if(a ==NULL && b ==NULL) return 1;
    if(a ==NULL || b==NULL) return 0;
    return a->data==b->data
            && same(a->lchid,b->lchild)
            && same(a->rchild,b->child);
}

判断平衡二叉树

// 左子树 右子树 balance=1 且左右子树高差小于等于1 平衡
// 最终判断 平衡 balance 1 不平衡balance 0
// 从底向上 
// c语言 不支持 int &a,这个写法是c++ ,本质应该都是传址
void judge(Tree *t,int & balance,int &h){
    int bl=0,br=0,h1=0,hr=0;        //左右子树 平衡标记和高度
    if(t==NULL){
        h=0;
        balance = 1;  
    }
    else if(t->lchild==NULL && t->rchild==NULL){
        h=1;
        balance = 1;
    }
    else{
        judge(t->lchild,bl,hl);			//bl代表了左子树平衡因子
        judge(t->rchild,br,hr);			//br代表了右子树平衡因子	
        h=(h1 > hr ? hl:hr)+1;			//该节点为根树高 h
        if(abs(hl-hr)<2)				//当左右子树高差 在-1 0 1
            balance= bl && br;       	//左右子树是否都平衡,平衡则该节点为根的树平衡
        else
            balance=0;
    }
}

交换二叉树左右子树

void swap(Tree * b){
	if(b){
		node*temp = b->lchild;
		b->lchild = b->rchild;
		b->rchild = temp;
		swap(b->lchild);
		swap(b->rchild);
	}
}

将二叉树转换为中缀表达式

void change(tree * root){				//根节点 和 叶子结点情况不用加括号
    test(root,1);
}
void test(tree* t,int deep){
    if(t==NULL)
        return ;	//空节点返回
    else if(t->left== NULL && t->right == NULL)
        printf("%s",t->data);	//叶子结点 输出操作数 不加括号
    else{
        if(deep>1) printf("(");
        test(t->left,deep+1);
        printf("%s",t->data);
        test(t->right,deep+1);
        if(deep>1)printf(")");
    }
}

二叉树wpl带权路劲长度

typedef struct Node{
    int weight;
    struct Node *lchild,*rchild;
}Node,*Tree;
int wpl(Tree root){
    return  preorder(root,0);		// 算得即所求
}
int preorder(Tree t,int deep){	//deep 高度
    static int w=0;		// w 带权长度
    if(t->lchild==NULL && t->rchild ==NULL)		//叶子节点 累加权值
        w+= deep * t->weight;
    if(t->lchild!=NULL)
        preorder(t->lchild,deep+1);
    if(t->rchild!=NULL)
        preorder(t->rchild,deep+1);
    return w;
}

十字链表法 有向图
多重邻接表 无向图
typedef struct {			// 邻接矩阵
    int Vex[Max];         // 顶点		(MaxVertexNum)
    int Edge[Max][Max];  // 邻接矩阵,0 表示没有边	
    int vexnum, arcnum;            // 顶点数和弧数
} Graph;					
//-------------------------------------分割线-------------
//邻接表
typedef struct ArcNode{		//边表节点
	int adjvex;				//弧所指向顶点位置
	struct ArcNode * next;	//指向下一条弧的指针
}ArcNode;
typedef struct 	VNode{
	VertexType data;		//顶点表节点
	ArcNode *first;			//指向第一条弧的指针
}VNode,AdjList[max];
typedef struct{
	AdjList vertices ;		//邻接表
	int vexnum, arcnum;		//顶点 弧
}Graph;

广搜

int visited[Max];                       // 辅助标记数组 0未访问 1访问
void BFSTraverse(Graph G){             // 遍历所有连通分量的BFS
    int i;
    for (i = 0; i < G.vexnum; i++)
        visited[i]=0;                   //初始化 所有节点未访问
    InitQueue(Q);                       //辅助队列
    for (i = 0; i < G.vexnum; i++){    // 遍历所有顶点,确保每个连通分量都被访问到
        if (!visited[i])
            BFS(G,i);
    }
}
void BFS(Graph G, int v){
    visit(v);
    visited[v] =1;
    EnQueue(Q);
    while(!isEmpyt(Q)) {
        DeQueue(Q,v);					//出队元素赋给v
        for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
            if(!visited[w]){
                visit(w);
                visited[w]=1;
                EnQueue(Q,w);           //将所有w相连未访问节点进队
            }
    }
}

深搜

int visited[Max];                       // 全局变量,辅助标记数组 0未访问 1访问
void DFSTraverse(Graph G){              // 遍历所有连通分量
    int i;
    for (i = 0; i < G.vexnum; i++)
        visited[i]=0;                   //初始化 所有未访问节点
    for (i = 0; i < G.vexnum; i++)      // 遍历所有顶点,确保每个连通分量都被访问到
        if (!visited[i])
            DFS(G,i);
}
void DFS(Graph G, int v){
    visit(v);
    visited[v] =1;
    for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
        if(!visited[w]){
            DFS(G,w);
    }
}

排序

折半插入排序

void search(int a[], int n) {
    int i, j, low, mid, high;
    for (i = 2; i <= n; i++) {// 从第二个元素开始,即 a[1] 到 a[n] 执行折半插入排序
        a[0] = a[i]; // 哨兵元素保存当前元素 a[i]
        low = 1; // 已排序子数组的起始位置
        high = i - 1; // 已排序子数组的结束位置
        while (low <= high) {
            mid = (low + high) / 2; // 计算中间位置
            if (a[mid] > a[0])// 如果中间位置的元素大于当前元素 a[0],将 high 移至 mid-1
                high = mid - 1;
            else
                low = mid + 1; // 否则将 low 移至 mid+1
        }
        for (j = i - 1; j >= low; --j)// 将大于a[0]的元素逐个后移为a[0] 腾出插入位置
            a[j + 1] = a[j];
        a[low] = a[0];// 插入 a[0] 到正确的位置
    }
}

快速排序

int Partion(int a[],int low,int high){
    int key =a[low];		//默认第一个元素基准
    while(low< high){
        while(low <high && a[high] >= key) --high;
        a[low] =a[high];
        while(low <high && a[low] <= key) ++low;
        a[high] =a[low];
    }
    a[low] =key;
    return low;
}
void QuickSort(int a[], int low,int high){
    if(low <high){
        int key =Partion(a,low,high);
        QuickSort(a,low,key-1); 
        QuickSort(a,key+1,high);
    }
}

划分序列 右边的元素比左边的大,右区间减左区间最大

void Sort(int a[],int n){
    int key,low=0,low1=0,high=n-1,high1=n-1,flag=1,k=n/2,i; //分区刚好一半满足
    // n从1开始 n个数, low1,high1 辅助调整low high 
    // 当基准刚好是 n/2前一个元素即 n/2 -1个元素,代表刚好均分
    int s1=0,s2=0;
    while(flag){
        key= a[low];
        while(low<high){    // 快排
            while(low<high && a[high] >= key) --high;
            if(low !=high) a[low] =a[high];
            while(low<high && a[low] <= key) ++low;
            if(low!=high) a[high]=a[low];
        }
        a[low] =key;
        if(low == k-1)      //将基准趋于中间
            flag=0;
        else{				//不然调整基准 直到是 n/2 -1
                if(low < k-1){
                    low1 = ++low;
                    high=high1;
                }
                else{
                    high1 =--high;
                    low =low1;
                }
            }
    }
    for(i=0;i<k;i++) s1+=a[i];
    for(i=k;i<n;i++) s2+=a[i];
    return s2-s1;
}

归并排序

int b[max]; // 全局变量 辅助变量用于复制a
void Merge(int a[], int low, int mid, int high){
    int i,j,k;
    for(k=low; k<=high;k++)
        b[k] =a[k];             //将 a元素 复制到 b
    for(i=low,j =mid+1,k=low;i<=mid && j<=high;k++){  //将复制后b中元素 按照新规律放回a
        if(b[i] <= b[j])        //比较b 左右两端中元素
            a[k] = b[i++];      //将小的放回a中
        else
            a[k] = b[j++];
    }
    while(i<=mid)   a[k++]=b[i++];  //当其中一个分区空了剩下的直接按顺序放回
    while(j<=high)   a[k++]=b[j++];
}
void MergeSort(int a[],int low,int high){
    if(low< high){
        int mid =(low+high)/2;      //对半分两个 子序列
        MergeSort(a,low,mid);       //递归左子序列
        MergeSort(a,mid+1,high);
        Merge(a,low,mid,high);      //归并
    }
}
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值