二叉树各种遍历功能的实现(c/c++)_实现二叉树各种遍历算法-程序员宅基地

技术标签: 算法  c++  c语言  数据结构  

目录

一、预备定义

1.自定义数据结构

2.关于栈和队列的自定义函数

栈:

队列:

二、根据完整先序序列,递归创建二叉树(二叉链表存储结构)

三、各种遍历

1.递归方式先序遍历

2.递归方式中序遍历

3.递归方式后序遍历

4.非递归方式前序遍历

5.非递归方式中序遍历

6.非递归方式后序遍历

7.层次遍历

8.递归销毁二叉树

四、功能菜单和主函数


一、预备定义

1.自定义数据结构

二叉树结点、循环顺序队列、数据栈结点、数据栈、指针栈结点,指针栈。

#define _CRT_SECURE_NO_WARNINGS  //去警告提示
#include <stdio.h>
#include <stdlib.h>

#define QUEUE_MAX_LENGTH 20  //最多存19个元素

// 二叉树结点的定义
typedef struct _BiNode
{
    char data;
    struct _BiNode* lchild;
    struct _BiNode* rchild;
}BiNode, * BiTree;        

// 固定长度的循序顺序队列结构体
typedef struct
{
    BiTree data[QUEUE_MAX_LENGTH];
    int front;  //指向队头元素的前一个元素
    int rear;  //指向队尾元素
} SeqQueue;


// 数据栈结点结构体  (非递归后序遍历时使用)
typedef struct DataNode
{
    char data;  // 数据域为char类型
    struct DataNode* next;
} DataStackNode;

// 数据栈结构体
typedef struct
{
    DataStackNode* top;  // 指向数据栈结点
} DataLinkedStack;


// 指针栈结点结构体
typedef struct PtrNode
{
    BiTree data;  // 数据域为BiTree类型
    struct PtrNode* next;
} PtrStackNode;

// 指针栈结构体
typedef struct
{
    PtrStackNode* top;  // 指向指针栈结点
} PtrLinkedStack;


2.关于栈和队列的自定义函数

初始化数据栈、进数据栈、出数据栈、判断数据栈是否为空。

初始化指针栈、进指针栈、出指针栈、判断指针栈是否为空、获取指针栈栈顶。

初始化队列、判断队列是否为空、判断队列是否为满、获取当前队列中有多少个元素、进队、出队、读取队头和队尾。

栈:

// 数据栈初始化为空栈
void initDataStack(DataLinkedStack& stack)
{
    stack.top = NULL;
}

/* 进栈一个元素 */
void pushDataStack(DataLinkedStack& stack, char e)
{
    DataStackNode* p;

    // 开辟空间,构造结点
    p = (DataStackNode*)malloc(sizeof(DataStackNode));
    p->data = e;
    p->next = NULL;

    // 入栈
    p->next = stack.top;
    stack.top = p;
}


/* 出栈一个元素 */
int popFromDataStack(DataLinkedStack& S, char& e)
{
    DataStackNode* p;  //出栈不需要为其开辟空间

    if (NULL != S.top)
    {
        p = S.top;
        S.top = p->next;

        e = p->data;
        free(p);

        return 1;        // 出栈成功
    }
    else
        return 0;        // 栈为空,出栈失败
}

/* 判断数据栈是否为空 */
int isEmptyDataStack(DataLinkedStack S)
{
    if (NULL == S.top)
        return 1;        // 栈为空,则返回1
    else
        return 0;        // 否则, 返回0
}


//

// 指针栈初始化为空栈
void initPtrStack(PtrLinkedStack& stack)
{
    stack.top = NULL;
}


/* 判断指针栈是否为空 */
int isEmptyPtrStack(PtrLinkedStack stack)
{
    if (NULL == stack.top)
        return 1;        // 栈为空,则返回1
    else
        return 0;        // 否则, 返回0
}

/* 进栈一个元素 */
void pushToPtrStack(PtrLinkedStack& stack, BiTree e)
{
    PtrStackNode* p;

    // 开辟空间,构造结点
    p = (PtrStackNode*)malloc(sizeof(PtrStackNode));
    p->data = e;
    p->next = NULL;

    // 入栈
    p->next = stack.top;
    stack.top = p;
}

/* 出栈一个元素 */
int popFromPtrStack(PtrLinkedStack& stack, BiTree& e)
{
    PtrStackNode* p;

    if (NULL != stack.top)
    {
        p = stack.top;
        stack.top = p->next;
        // 或stack.top = stack.top->next;

        e = p->data;
        free(p);

        return 1;        // 出栈成功
    }
    else
        return 0;        // 栈为空,出栈失败
}

/* 获取栈顶 */
int getTopOfPtrStack(PtrLinkedStack stack, BiTree& e)
{
    if (NULL != stack.top)
    {
        e = stack.top->data;
        return 1;        // 栈不为空,获取栈顶成功,则返回1
    }
    else
        return 0;        // 否则, 返回0
}

队列:

// 初始化为空队列
// 队头和队尾指向顺序队列数组中的最后一个元素
void initQueue(SeqQueue& queue)
{
    queue.front = queue.rear = QUEUE_MAX_LENGTH - 1;
}


// 判断队列是否为满
// 队尾指针下一个指向队头时队满
int queueIsFull(SeqQueue queue)
{
    if (queue.front == (queue.rear + 1) % QUEUE_MAX_LENGTH)
        return 1;
    else
        return 0;
}

// 判断队列是否为空
// 队头队尾指向同一元素时队列为空
int queueIsEmpty(SeqQueue queue)
{
    if (queue.front == queue.rear)
        return 1;
    else
        return 0;
}


/* 进队一个元素 */
int inQueue(SeqQueue& queue, BiTree e)
{
    if (1 == queueIsFull(queue))
        return 0;            // 队列已满,无法进队
    else
    {
        queue.rear = (queue.rear + 1) % QUEUE_MAX_LENGTH;
        queue.data[queue.rear] = e;

        return 1;            // 进队成功
    }
}


/* 出队一个元素 */
int outQueue(SeqQueue& queue, BiTree& e)
{
    if (1 == queueIsEmpty(queue))
        return 0;            // 队列已空,无法出队
    else
    {
        queue.front = (queue.front + 1) % QUEUE_MAX_LENGTH;  
        e = queue.data[queue.front];

        return 1;            // 出队成功(实际元素仍存在于数组中,逻辑上出队成功)
    }
}


// 获取当前队列中有多少个元素
int getElemNum(SeqQueue queue)
{
    return (queue.rear - queue.front + QUEUE_MAX_LENGTH) % QUEUE_MAX_LENGTH;
}

/* 读取队头和队尾元素的信息 */
int getFrontRear(SeqQueue queue, BiTree& ef, BiTree& er)
{
    if (1 == queueIsEmpty(queue))
        return 0;            // 队列已空,无队头和队尾
    else
    {
        ef = queue.data[queue.front + 1];
        er = queue.data[queue.rear];

        return 1;
    }
}

二、根据完整先序序列,递归创建二叉树(二叉链表存储结构)

BT.dat 文件内容(完整先序序列):ABD#G##E##C#FH###

递归算法(图文详解)_碎涛的博客-程序员宅基地_递归算法

个人易错点:每次递归“归来”时都要从开始递归的代码行,继续执行后续代码,直到进行下一次“归来”,而不是忽略后续代码的执行直接继续下一次“归来”。

BiNode* createBiTree(FILE* fp)
{
    char ch;
    BiNode* p;

    // 从文件中依次读取各个结点值(空树为#)
    ch = fgetc(fp);

    if ('#' != ch)
    {
        // 开辟空间,构造结点,最后递归创建左右子树
        p = (BiNode*)malloc(sizeof(BiNode));
        p->data = ch;

        // 递归创建ch结点的左子树
        p->lchild = createBiTree(fp);

        // 递归创建ch结点的右子树
        p->rchild = createBiTree(fp);

        return p;  //返回根节点地址
    }
    else
        return NULL;
}

三、各种遍历

1.递归方式先序遍历

void preOrder(BiTree root)
{
    if (root == NULL) {  // 特殊情况优先考虑
        return;
    }
    printf("%2c", root->data);
    preOrder(root->lchild);
    preOrder(root->rchild);
}

2.递归方式中序遍历

void inOrder(BiTree root)
{
    if (root == NULL) {
        return;
    }
    inOrder(root->lchild);
    printf("%2c", root->data);
    inOrder(root->rchild);

}

3.递归方式后序遍历

void postOrder(BiTree root)
{
    if (root == NULL) {
        return;
    }
    postOrder(root->lchild);
    postOrder(root->rchild);
    printf("%2c", root->data);
}

4.非递归方式前序遍历

利用栈。

先将根结点输出,然后将其右孩子进指针栈、左孩子进指针栈,先右后左进栈则先左后右出栈

当指针栈不为空时,出栈一个元素,对其进行先序遍历:先将根结点输出,然后将根结点的右、左孩子依次进栈。

void nonRecursionPreOrder(BiTree root)
{
    PtrLinkedStack ptrStack;
    BiTree subRoot = NULL;

    // 先将栈初始化为空
    initPtrStack(ptrStack);

    // 先序遍历时,根应最先访问,所以先将根结点输出
    printf("%2c", root->data);
 

    // 再将右子树和左子树根结点的地址,依次进指针栈ptrStack  
    //先右后左进栈,先左后右出栈
    if (NULL != root->rchild)
        pushToPtrStack(ptrStack, root->rchild);

    if (NULL != root->lchild)
        pushToPtrStack(ptrStack, root->lchild);

    // 当PLStack栈不为空时,说明还有子树没有遍历
    while (0 == isEmptyPtrStack(ptrStack))
    {
        // 出栈一个元素(某棵子树根结点的地址) (左)
        popFromPtrStack(ptrStack, subRoot);

        // 先将根结点的值输出
        printf("%2c", subRoot->data);
      

        // 再将右子树和左子树根结点的地址,依次进指针栈ptrStack
        if (NULL != subRoot->rchild)
            pushToPtrStack(ptrStack, subRoot->rchild);

        if (NULL != subRoot->lchild)
            pushToPtrStack(ptrStack, subRoot->lchild);
    }
}

5.非递归方式中序遍历

(1)根结点先进栈。

(2)当栈不为空时,出栈一个元素:

        若为叶子结点则直接输出;

        若不是叶子结点,判断其第几次出栈:看栈顶是否为自己的右孩子,若是则为第二次出栈,若不是则为第一次出栈。对于没有右孩子的结点,进栈时将根节点多进一次栈,此时若为第二次出栈则其右孩子为自己。

                第一次出栈,代表以自己为根的子树,将其分解为三部分,并按 “右根左”的顺序进栈。

                第二次出栈:代表自己,可直接输出。 

void nonRecursionInOrder(BiTree root)
{
    PtrLinkedStack ptrStack;        // 定义一个结点指针型栈
    BiTree outElem, topElem;    // 分别用来保存出栈元素和栈顶元素

    // 先将指针栈初始化为空
    initPtrStack(ptrStack);

    // 二叉树的根进栈
    if (NULL != root)
        pushToPtrStack(ptrStack, root);

    // 当PLStack栈不为空时,说明还有子树没有遍历
    while (0 == isEmptyPtrStack(ptrStack))
    {
        // 出栈一个元素(某棵子树根结点的地址)
        popFromPtrStack(ptrStack, outElem);

        // 如果出栈的是叶子结点,则直接输出;
        if (NULL == outElem->lchild && NULL == outElem->rchild)
            printf("%2c", outElem->data);
        else
        {
            // 如果出栈的结点不是叶子
            if (1 == getTopOfPtrStack(ptrStack, topElem))  //判断是否成功获取栈顶
            {
                // 出栈时栈顶为其右孩子则说明其第二次出栈,代表自己出栈,可直接输出(孩子在栈里说明自己已被拆分进栈过一次)
                if (outElem->rchild == topElem) {
                    printf("%2c", outElem->data);
                }
                else if (topElem == outElem) {     // 栈顶等于自己,说明出栈结点无右孩子,当前栈顶是多进栈的
                    printf("%2c", outElem->data);
                    popFromPtrStack(ptrStack, outElem);  //扔掉重复进栈的根,因为该结点是因为当前结点无右孩子而多进栈的
                }
                else
                {
                    if (NULL != outElem->rchild)
                        pushToPtrStack(ptrStack, outElem->rchild);        // 右子树的根进栈
                    else
                    {
                        //对于没有右孩子的,虚构一个等于自己的右孩子(进两次栈),这样当栈顶为自己则表示第二次出栈
                        pushToPtrStack(ptrStack, outElem);
                    }

                    pushToPtrStack(ptrStack, outElem);                // 二叉树的根进栈

                    if (NULL != outElem->lchild)
                        pushToPtrStack(ptrStack, outElem->lchild);        // 左子树的根进栈   
                }
            }
            // 若获取栈顶失败,出栈元素必须分解为三部分,并按“右根左”的顺序进栈。
            else 
            {
                if (NULL != outElem->rchild)
                    pushToPtrStack(ptrStack, outElem->rchild);        // 右子树的根进栈
                else
                {
                    //对于没有右孩子的,虚构一个等于自己的右孩子(进两次栈),若栈顶为自己则表示第二次出栈
                    pushToPtrStack(ptrStack, outElem);
                }

                pushToPtrStack(ptrStack, outElem);                // 二叉树的根进栈

                if (NULL != outElem->lchild)
                    pushToPtrStack(ptrStack, outElem->lchild);        // 左子树的根进栈   
            }

        }
            
            
    }
    
}


/*    下面这个函数,也可以进行非递归中序遍历,
    但是在遍历过程中,二叉链表将被破坏,所以一般不用这种方法!*/
    // 会破坏二叉链表存储结构的非递归方式中序遍历
void problematicNonRecursionInOrder(BiTree root)
{
    PtrLinkedStack ptrStack;    // 定义一个结点指针型栈
    BiTree leftChild;

    // 先将栈初始化为空
    initPtrStack(ptrStack);

    // 二叉树的根进栈
    if (NULL != root)
        pushToPtrStack(ptrStack, root);

    // 当PLStack栈不为空时,说明还有子树没有遍历
    while (0 == isEmptyPtrStack(ptrStack))
    {
        BiTree p = NULL;

        // 出栈一个元素(某棵子树根结点的地址)
        popFromPtrStack(ptrStack, p);

        // 如果该根结点的左右子树都不存在(即为孤立结点),则直接输出;
        // 否则,必须分解为三部分按“右根左”的顺序进栈。
        // 注意:根结点也作为一个单独的子树,所以其左右指针域应先设置为NULL。
        if (NULL == p->lchild && NULL == p->rchild)
        {
            printf("%2c", p->data);
        }
        else
        {
            leftChild = p->lchild;                    // 先保留左子树根的地址

            if (NULL != p->rchild)
                pushToPtrStack(ptrStack, p->rchild);    // 右子树的根进栈

            p->lchild = NULL;                 //清空左右孩子域,进去孤立结点
            p->rchild = NULL;
            pushToPtrStack(ptrStack, p);                // 二叉树的根进栈

            if (NULL != leftChild)
                pushToPtrStack(ptrStack, leftChild);    // 左子树的根进栈
        }
    }
}

6.非递归方式后序遍历

设置指针栈和数据栈。数据栈数据域为char,指针栈数据域为BiTree。

进栈:

        数据栈:根→根右→根左

        指针栈:(栈底)根的左子树→根的右子树

                当指针栈不为空时,说明还有子树没有遍历:出栈,将其根进数据栈,将其左右子树依次进指针栈。

将数据栈元素出栈,即可得到后序遍历序列。

// Function5--非递归方式后序遍历
void nonRecursionPostOrder(BiTree root)
{
    DataLinkedStack dataStack;        // 定义一个输出数据栈
    PtrLinkedStack ptrStack;            // 定义一个结点指针型栈

    // 先将两个栈都初始化为空
    initDataStack(dataStack);
    initPtrStack(ptrStack);

    // 后序遍历时,根应最后访问,所以先将根结点的值进数据栈DLStack
    pushDataStack(dataStack, root->data);

    // 再将左子树和右子树根结点的地址,依次进指针栈PLStack  
    if (NULL != root->lchild)
        pushToPtrStack(ptrStack, root->lchild);

    if (NULL != root->rchild)
        pushToPtrStack(ptrStack, root->rchild);  

    // 当PLStack栈不为空时,说明还有子树没有遍历
    while (0 == isEmptyPtrStack(ptrStack))
    {
        BiTree pNode = NULL;

        // 出栈一个元素(某棵子树根结点的地址)
        popFromPtrStack(ptrStack, pNode);

        // 先将根结点的值进数据栈DLStack
        pushDataStack(dataStack, pNode->data);

        // 再将左子树和右子树根结点的地址,依次进指针栈PLStack
        if (NULL != pNode->lchild)
            pushToPtrStack(ptrStack, pNode->lchild);

        if (NULL != pNode->rchild)
            pushToPtrStack(ptrStack, pNode->rchild);
    }

    // 数据栈dataStack依次出栈,即可得到后序遍历序列
    while (0 == isEmptyDataStack(dataStack))
    {
        char value = ' ';

        // 出栈一个元素(某结点的值),并输出
        popFromDataStack(dataStack, value);
        printf("%2c", value);
    }
}

7.层次遍历

void hierarchicalOrder(BiTree root)
{
    BiTree pNode = NULL;
    SeqQueue queue;

    // 初始化为空队列
    initQueue(queue);

    // 树根结点的地址先进队
    inQueue(queue, root);

    // 只要队列不为空,则一直循环
    while (queueIsEmpty(queue) == 0) {
        outQueue(queue, pNode);
        printf("%2c", pNode->data);

        if (pNode->lchild != NULL)
            inQueue(queue, pNode->lchild);
        if (pNode->rchild != NULL)
            inQueue(queue, pNode->rchild);

    }


}

8.递归销毁二叉树

void destroy(BiTree root)
{
    if (NULL != root)
    {
        if (NULL != root->lchild)        // 左子树不为空,则递归销毁左子树
            destroy(root->lchild);

        if (NULL != root->rchild)        // 右子树不为空,则递归销毁右子树
            destroy(root->rchild);

        printf("%c node has been freed!\n", root->data);
        free(root);        // 最后直接释放根结点
    }
}

四、功能菜单和主函数

// 功能菜单
void menu()
{
    printf("\n\t************************Binary Linked List************************\n");
    printf("\t*    1--Read data from a file to create a binary tree            *\n");
    printf("\t*    2--PreOrder, InOrder and PostOrder traversal by recursion   *\n");
    printf("\t*    3--PreOrder traversal by non-recursion                      *\n");
    printf("\t*    4--InOrder traversal by non-recursion                       *\n");
    printf("\t*    5--PostOrder traversal by non-recursion                     *\n");
    printf("\t*    6--Hierarchical traversal (using queue)                     *\n");
    printf("\t*    7--Destroy the entire binary tree                           *\n");
    printf("\t*    8--Clear screen                                             *\n");
    printf("\t*    0--Exit program                                             *\n");
    printf("\t******************************************************************\n");
    printf("\tPlease select a menu item:");
}

int main()
{
    int choice;
    char c;
    BiTree root = NULL;        
    FILE* fpFrom;

    system("chcp 65001");  // 设置window控制台(CMD或命令行窗口)为UTF-8格式

    while (1)
    {
        menu();
        scanf("%d", &choice);

        switch (choice)
        {
        case 1:
            if (NULL != root)
            {
                printf("The current binary tree is not empty, please destroy it before rebuild!\n");
            }
            else
            {
                // 因为createBiTree()函数递归时要不断从文件中读取字符,所以先打开文件
                // 如果在createBiTree()函数中每读一个字符,就打开并关闭文件一次,则效率太低
                fpFrom = fopen("BT.dat", "r");
                if (NULL == fpFrom)
                {
                    printf("File containing complete PreOrdered sequence cannot be opened, binary tree creation failed!\n");
                    break;
                }

                root = createBiTree(fpFrom);

                fclose(fpFrom);
                printf("Binary tree created successfully!\n");
            }
            break;

        case 2:
            if (NULL != root)
            {
                printf("The PreOrdered sequence is as follows:");
                preOrder(root);

                printf("\nThe InOrdered sequence is as follows:");
                inOrder(root);

                printf("\nThe PostOrdered sequence is as follows:");
                postOrder(root);

                printf("\n");
            }
            else
                printf("The current binary tree is empty, please create the binary tree first!\n");
            break;

        case 3:
            if (NULL != root)
            {
                printf("The non-recursive PreOrdered sequence is as follows:\n");
                nonRecursionPreOrder(root);
                printf("\n");
            }
            else
                printf("The current binary tree is empty, please create the binary tree first!\n");
            break;

        case 4:
            if (NULL != root)
            {
                printf("The non-recursive InOrdered sequence is as follows:\n");
                nonRecursionInOrder(root);
                printf("\n");
            }
            else
                printf("The current binary tree is empty, please create the binary tree first!\n");
            break;

        case 5:
            if (NULL != root)
            {
                printf("The non-recursive PostOrder sequence is as follows:\n");
                nonRecursionPostOrder(root);
                printf("\n");
            }
            else
                printf("The current binary tree is empty, please create the binary tree first!\n");
            break;

        case 6:
            if (NULL != root)
            {
                printf("The hierarchical ordered sequence is as follows:\n");
                hierarchicalOrder(root);
                printf("\n");
            }
            else
                printf("The current binary tree is empty, please create the binary tree first!\n");
            break;

        case 7:
            if (NULL != root)
            {
                destroy(root);
                root = NULL;
                printf("The binary tree destroyed successfully!\n");
            }
            else
                printf("The current binary tree is empty, no need to destroy!\n");
            break;

        case 8:
            system("cls");
            break;

        case 0:
            // 关闭保存结果的文件后,再退出程序
            exit(0);
            break;

        default:
            // If the user enters an alphabetic menu item instead of an integer, 
            // the buffer needs to be emptied
            while ((c = getchar()) != '\n' && c != EOF);
            printf("The menu item you entered does not exist, please select it again!\n");
        }
    }
    return 0;
}

五、代码实现

测试数据:ABD#G##E##C#FH###

(放在文件"BT.dat"中)

 (二进制文件要与源程序.cpp放在一个文件夹下)

我实现了一下是没问题的。

说明:本文代码是我的数据结构作业,是老师写的,因为理解不透彻所以自己写了注释和分析,发现要自己写还是有点困难qwq,好歹自己理了一下思路,希望对你们有帮助.OvO.

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_62800173/article/details/127820112

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法