《数据结构》失眠复习,1-05 大物期末考试

数据结构算法训练--01顺序表的逆置_哔哩哔哩_bilibili

//顺序表逆置原地逆置,空间复杂度O(1)
typedef struct {
    int data[100];  // 假设顺序表存储int类型,长度100
    int length;     // 顺序表实际长度
} Sqlist;
void traversal(Sqlist & L){
    int i=0,j=L.length-1;
    while(i<j){
        int temp;
        temp=L.data[i];
        L.data[i]=L.data[j];
        L.data[j]=temp;
        i++;
        j--;
    }
}

数据结构算法训练--05链表的原地逆置_哔哩哔哩_bilibili

typedef  int Elemtype;
typedef struct LNode{
   Elemtype data;
   struct LNode *next;
}LNode,*LinkList;

//白皮书加了个判断是不是非递减有序
int isorted(LinkList L){
    if(!L||L->next==NULL)return 1;
    LNode* pre=L->next;
    LNode*cur=pre->next;
    while(cur){
        if(pre->data>cur->data)return 0;
      	else {
            pre=cur;
            cur=cur->next;
        }
    }
    return 1;
}
void traversal(LinkList L){
    if(!isorted(L))
        printf("It is out of order");
    else//逆置
    {
        LNode *p=L->next;
        LNode *q;
        L->next=NULL;
        while(p){
            q=p->next;
            p->next=L->next;//头结点后面的节点
            L->next=p;
            p=q;
        }
    }
}
//求叶节点数目
typedef int Elemtype;
typedef struct BTNode{
    Elemtype data;
    struct BTNode *lchild;
    struct BTNode *rchild;
}BTNode,*BiTree;
int count(BiTree T){
    if(!T)return 0;
    if(T->lchild==NULL&&T->rchild==NULL)return 1;
    return count(T->lchild)+count(T->rchild);
}
int NRcount(BiTree T){
    
    
}
//求总结点数目
int count(BiTree T){
    if(!T) return 0;
    return count(T->lchild)+count(T->rchild)+1;
}
//层次
int NRcount(BiTree T) {
    if(!T) return 0;
    SqQueue Q;
    InitQueue(&Q);
    EnQueue(&Q, T);
    int cnt = 0;
    while(!EmptyQueue(&Q)) {
        BiTree p;
        DeQueue(&Q, &p);
        cnt++;
        if(p->lchild) EnQueue(&Q, p->lchild);
        if(p->rchild) EnQueue(&Q, p->rchild);
    }
    return cnt;
}
//先序
int PreOrderCount(BiTree T) {
    if(!T) return 0;
    Stack S;
    InitStack(&S);
    BiTree p = T;
    int cnt = 0; // 节点计数
    while(p != NULL || !EmptyStack(&S)) {
        while(p != NULL) {
            cnt++; // 访问节点时计数(先序核心:入栈前计数)
            Push(&S, p);
            p = p->lchild;
        }
        Pop(&S, &p);
        p = p->rchild;
    }
    return cnt;
}
int InOrderCount(BiTree T) {
    if(!T) return 0;
    Stack S;
    InitStack(&S);
    BiTree p = T;
    int cnt = 0;
    while(p != NULL || !EmptyStack(&S)) {
        while(p != NULL) {
            Push(&S, p);
            p = p->lchild;
        }
        Pop(&S, &p);
        cnt++; // 访问节点时计数(中序核心:出栈后计数)
        p = p->rchild;
    }
    return cnt;
}
// 后序非递归统计总结点
int PostOrderCount(BiTree T) {
    if(!T) return 0;
    Stack S;
    InitStack(&S);
    BiTree p = T, pre = NULL;
    int cnt = 0;
    while(p != NULL || !EmptyStack(&S)) {
        while(p != NULL) {
            Push(&S, p);
            p = p->lchild;
        }
        Pop(&S, &p);
        if(p->rchild == NULL || p->rchild == pre) {
            cnt++; // 访问节点时计数(后序核心:右子树处理完计数)
            pre = p;
            p = NULL;
        } else {
            Push(&S, p);
            p = p->rchild;
        }
    }
    return cnt;
}
//求二叉树深度,递归两种方法,非递归队列实现
int depth(BiTree T){
    if(!T)return 0;
    int l=depth(T->lchild);
    int r=depth(T->rchild);
    if(l>r)
        return l+1;
    else 
        return r+1;
    //等价于return l>r?l+1:r+1;
}
int NRdepth(BiTree T) {
    if(!T) return 0;
    SqQueue Q;
    InitQueue(&Q);
    EnQueue(&Q, T);
    int d = 0;
    while(!EmptyQueue(&Q)) {
        int levelSize = (Q->rear - Q->front + MAXQSIZE) % MAXQSIZE;
        for(int i=0; i<levelSize; i++) {
            BiTree p;
            DeQueue(&Q, &p);
            if(p->lchild) EnQueue(&Q, p->lchild);
            if(p->rchild) EnQueue(&Q, p->rchild);
        }
        d++;
    }
    return d;
}
//树的遍历算法


void vist(BiTree T){
    printf("%d",T->data);
}
void PreOrder(BiTree T){
    if(!T)  return;
    else
        vist(T);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
}
void InOrder(BiTree T){
    if(!T)  return;
    else 
    InOrder(T->lchild);
    vist(T);
    InOrder(T->rchild);
}
void PostOrder(BiTree T){
    if(!T)  return;
    else
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    vist(T);
}
void leveltraversal(BiTree T){
   	if (!T) return;

	SqQueue Q;
	InitQueue(&Q);
	EnQueue(&Q, T);

	while (QueueEmpty(&Q) != OK)
	{
		BiTree p;
		DeQueue(&Q, &p);
		vist(p);

		if (p->lchild)
		{
			EnQueue(&Q, p->lchild);
		}
		if (p->rchild)
		{
			EnQueue(&Q, p->rchild);
		}
	}
}

//先序、中序、后序非递归实现
void NRPreOrder(BiTree T){
    if(!T)return;
    Stack S;
    InitStack(&S);
   	BiTree p=T;
    while(p!=NULL||!EmptyStack(S)){
        while(p!=NULL){
            vist(p);
            Push(&S,p);
            p=p->lchild;
        }
        Pop(&S,&p);
        p=p->rchild;
    }
    
}
void NRInOrder(BiTree T){
    if(!T)return;
    Stack S;
    InitStack(&S);
   	BiTree p=T;
    while(p!=NULL||!EmptyStack(S)){
        while(p!=NULL){
            
            Push(&S,p);
            p=p->lchild;
        }
        Pop(&S,&p);
        vist(p);
        p=p->rchild;
    }
    
}
void NRPostOrder(BiTree T){
    if(!T) return;
    Stack S;
    InitStack(&S); 
    BiTree p = T;
    BiTree pre = NULL;
    while(p != NULL || !EmptyStack(&S)){
        while(p != NULL){
            Push(&S, p);
            p = p->lchild;
        }
        Pop(&S, &p);
        // 后序核心:右子树空 或 右子树已访问 → 访问当前节点
        if(p->rchild == NULL || p->rchild == pre) {
            vist(p);
            pre = p;   // 更新已访问节点
            p = NULL;  // 避免重复走左子树
        } else {
            Push(&S, p); // 右子树未处理,重新入栈
            p = p->rchild;
        }
    }
}
    


//交换左右孩子
void swap(BiTree T){
    if(!T) return;
    BiTree temp;
    temp=T->lchild;
    T->lchild=T->rchild;
    T->rchild=temp;
    swap(T->lchild);
    swap(T->rchild);
    
}
//判断两颗二叉树是否相等
int isequals(BiTree T1,BiTree T2){
    if(!T1&&!T2) return 1; //两棵树都为空
    if (!T1 || !T2) return 0;//有一棵树不为空,另一颗为空
    if(T1->data!=T2->data) return 0;
    return isequals(T1->lchild,T2->lchild)&&isequals(T1->rchild,T2->rchild);
}
//非递归写法
// 非递归判断两棵二叉树相等
int NRisequals(BiTree T1, BiTree T2) {
    // 步骤1:初始化两个队列,分别存储T1、T2的节点(层序遍历)
    SqQueue Q1, Q2;
    InitQueue(&Q1);
    InitQueue(&Q2);
    
    // 步骤2:根节点入队(空节点也入队,保证结构对比)
    EnQueue(&Q1, T1);
    EnQueue(&Q2, T2);
    
    // 步骤3:层序遍历,逐节点对比
    while (!EmptyQueue(&Q1) && !EmptyQueue(&Q2)) {
        BiTree p1, p2;
        // 出队:各取一个节点
        DeQueue(&Q1, &p1);
        DeQueue(&Q2, &p2);
        
        // 情况1:两个节点都空 → 结构一致,继续对比下一个节点
        if (p1 == NULL && p2 == NULL) {
            continue;
        }
        // 情况2:一个空、一个非空 → 结构不一致,返回0
        if (p1 == NULL || p2 == NULL) {
            return 0;
        }
        // 情况3:都非空但值不同 → 不相等,返回0
        if (p1->data != p2->data) {
            return 0;
        }
        
        // 情况4:都非空且值相同 → 左右孩子入队(空孩子也入队)
        EnQueue(&Q1, p1->lchild);
        EnQueue(&Q2, p2->lchild);
        EnQueue(&Q1, p1->rchild);
        EnQueue(&Q2, p2->rchild);
    }
    
    // 步骤4:所有节点对比完成,且两个队列都空 → 相等
    return EmptyQueue(&Q1) && EmptyQueue(&Q2);
}
//求树宽
int getTreeWidth(BiTree T) {
    if (!T) return 0;
    BiTree queue[MAXQSIZE]; // 直接用数组模拟队列,省掉结构体
    int front = 0, rear = 0;
    queue[rear++] = T;
    int maxWidth = 0;
    
    while (front < rear) {
        int levelSize = rear - front; // 非循环队列,直接相减
        if (levelSize > maxWidth) maxWidth = levelSize;
        
        for (int i = 0; i < levelSize; i++) {
            BiTree p = queue[front++];
            if (p->lchild) queue[rear++] = p->lchild;
            if (p->rchild) queue[rear++] = p->rchild;
        }
    }
    return maxWidth;
}
//求单分支节点数目
int cnt1(BiTree T)
{
	if (!T)
		return 0;
	// 判断当前结点是否为单分支结点
	if ((T->lchild && !T->rchild) || (!T->lchild && T->rchild))
	{
		return 1 + cnt1(T->lchild) + cnt1(T->rchild);
	}
	else
	{
		return cnt1(T->lchild) + cnt1(T->rchild);
	}
}
//求双分支节点数目
int numbers(BiTree T){
    if(!T) return 0;
    if(T->lchild&&T->rchild)
        return 1+numbers(T->lchild)+numbers(rchild);
    else 
        return numbers(T->lchild)+numbers(rchild);
}
//广义表非递归建立二叉树
// 广义表非递归建二叉树
//A(B(D,E),C(,F))
Status CreateBiTreeFromGeneralList(BiTree *T, const char *str, int *count)
{
    if (count) *count = 0;
    if (!T || !str)
        return ERROR;   *T = NULL;
    Stack S;
    InitStack(&S);
    BiTree p = NULL;
    int k = 0;  //1左孩子,2右孩子

    for (int i = 0; str[i] != '\0'; ++i)
    {
        char ch = str[i];
        if (ch == ' ' || ch == '\t' || ch == '\n' )
            continue;
      
        //字母,数字都可做节点
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))
        {
            p = (BiTree)malloc(sizeof(BiTNode));
            p->data = ch;
            p->lchild = p->rchild = NULL;
            if (count) (*count)++;
            if (*T == NULL)
                *T = p;
            else if (k == 1)
            {
                BiTree top = GetStackTop(&S);
                if (top)
                    top->lchild = p;
            }
            else if (k == 2)
            {
                BiTree top = GetStackTop(&S);
                if (top)
                    top->rchild = p;
            }
        }
        else if (ch == '(')
        {
            //左孩子入栈
            PushStack(&S, p);
            k = 1; 
        }
        else if (ch == ',')
        {
            k = 2;
        }
        else if (ch == ')')
        {
            PopStack(&S, &p);
        }
    }
    return OK;
}
posted @ 2026-01-25 19:35  叶臧  阅读(0)  评论(0)    收藏  举报