吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

文件系統-多叉樹與二叉樹的轉化

冬至子 ? 來源:編程外星人 ? 作者:怪蛙 ? 2023-10-11 10:06 ? 次閱讀

在這一節中,我們來學習如何使用程序來實現一棵文件樹。在上一節中,我們了解到使用文件樹的方式來整合計算機中所有的資源,而這一棵文件樹則是一棵多叉樹。也就是說,樹上的每一個節點都可能有多個子節點。

而這樣的一棵多叉樹在計算機中來實現是較為復雜的,使用起來也不方便。例如我們想要為節點1增加一個子節點2,之后再為節點1增加一個子節點3,之后再為節點1增加一個子節點4。整個過程如下圖:

圖片

由于這是一棵多叉樹,因此節點1可能具有多個子節點。這樣一來,在為節點1分配內存時,我們就無法確定的為其分配指定大小,由于樹型結構的特點,我們需要使用一個指針變量用于指向其一個子節點,而如果其具有2個子節點,則需要2個指針變量,如果其具有3個子節點,則需要3個指針變量。

于是對于多叉樹來說,當一個節點增加一個子節點時,當前節點也需要發生變化,也就是需要重新申請一個較大的內存空間用于存放更多的指針變量。同樣的,當一個節點的子節點被刪除時,也需要重新申請內存,釋放多余的指針變量。這對于編程實現多叉樹來說,是很復雜的,也是低效的。因此我們有必要尋找一種簡潔的辦法來處理多叉樹的實現問題。

我們知道,使用計算機編程來實現一個二叉樹是非常簡單的,每一個節點除了實際數據區域外只需要額外兩個指針用于存放其左孩子節點和右孩子節點即可,而且其內存申請和釋放都很簡潔。二叉樹就是每一個節點的子節點最多不能超過2個節點,如下圖則是一個二叉樹:

圖片

為了解決多叉樹的問題,我們自然想到是否能將一個多叉樹轉化為一個二叉樹,并使用計算機程序來實現呢?答案是肯定的!其實,每一棵多叉樹都可以轉化為一個等價的二叉樹。進而可以將一個具有多個多叉樹的森林轉化為一個與之等價的二叉樹。

具體轉化的過程是這樣的:我們可以定義一個二叉樹的節點,并定義兩個指針變量,這兩個指針變量分別為指向其“子節點”(child)和其“兄弟節點”(sibling),也就是說,一個二叉樹的兩個叉,左側表示其孩子,而右側表示其兄弟。于是我們就可以將一個多叉樹轉化一個二叉樹,具體轉化過程如下:

圖片

上圖中的多叉樹和二叉樹是等價的,這兩棵樹所表示的內容完全一致,只是在結構上不同而已。也就是說這棵多叉樹可以轉化為二叉樹,二叉樹也可以轉化為多叉樹,本質上講它們二者是可以相互轉化的,而沒有任何的不同。

對于這棵二叉樹來講,其“左叉”表示其孩子節點,而“右叉”表示其兄弟節點。而二叉樹在計算機程序中是比較容易實現的。接下來我們就定義這樣一棵二叉樹,用于表示其原有的多叉樹:

typedef struct vfs_node_s
{
  struct vfs_node_s *child;
  struct vfs_node_s *sibling;
  char name[200];
} vfs_node_s;

我們簡單的定義name屬性為表示這個節點的數據內容,而左叉child為其子節點,而右叉sibling為其兄弟節點。然后實現兩函數用于初始化和銷毀這個虛擬文件樹:

int vfs_init(void)
{
  vfs = malloc(sizeof(vfs_s));
  vfs- >root = malloc(sizeof(vfs_node_s));
  strncpy(vfs- >root- >name, "/", NODE_NAME_SIZE);
  vfs- >root- >child = NULL;
  vfs- >root- >sibling = NULL;


  return 0;
}


int vfs_destory(void)
{
  vfs_destory_r(&vfs- >root);
  free(vfs);
  return 0;
}

完成初始化和銷毀虛擬文件樹之后我們再來實現對任意節點進行的插入和刪除操作,也就是說針對虛擬文件樹,我們在指定位置插入一個新的節點:

int vfs_insert_node(char *path, file_operations_s ops)
{
  if (path[0] != '/')
  {
    return -1;
  }
  //插入子節點,調用遞歸函數
  int ret = vfs_insert_node_r(&vfs- >root- >child, &path[1], ops);
  return ret;
}


int vfs_insert_node_r(vfs_node_s **node, char *abs_path, file_operations_s ops)
{
  if (node == NULL)
  {
    return -1;
  }
  if (abs_path == NULL)
  {
    return -1;
  }
  if (abs_path[0] == 0)
  {
    return -1;
  }
  char node_name[NODE_NAME_SIZE] = {0};
  //找到虛擬文件樹上的指定路徑
  char *p = abs_path;
  for (int i = 0; *p != '/' && *p != 0 && i < NODE_NAME_SIZE; i++)
  {
    node_name[i] = *p++;
  }
  if (*p == '/' && *p != 0)
  {
    p++;
  }
  //查找其所有兄弟節點
  while (*node != NULL)
  {
    //找到兄弟節點
    if (strcmp((*node)- >name, node_name) == 0)
    {
      //遞歸執行其子節點插入操作
      return vfs_insert_node_r(&(*node)- >child, p, ops);
    }
    node = &(*node)- >sibling;
  }


  //最后生成一個新節點
  vfs_node_s *node_new = malloc(sizeof(vfs_node_s));
  strncpy(node_new- >name, node_name, NODE_NAME_SIZE);
  node_new- >child = NULL;
  node_new- >sibling = NULL;
  *node = node_new;
  //將新節點插入
  if (*p != 0)
  {
    return vfs_insert_node_r(&node_new- >child, p, ops);
  }
  return 0;
}

這樣,我們就完成了二叉樹的創建、銷毀與插入功能,當然還應該實現針對指定節點的刪除功能,這里我們不再給出具體實現代碼,請讀者自行完成。這樣的二叉樹就可以完整的表示我們計算機中的虛擬文件系統(根節點是虛擬節點,并非是實際存在的,Linux系統中的根節點是實際的硬盤分區,因此Linux的文件系統不是虛擬文件系統)。

此后我們就可以用這一棵二叉樹來表示計算機中的所有資源了,具體方式則是將資源抽象成一個文件,掛載到文件系統中,成為文件系統中的一個節點,這樣就可以方便用戶管理和使用這些資源了。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 計算機
    +關注

    關注

    19

    文章

    7536

    瀏覽量

    88638
  • Linux系統
    +關注

    關注

    4

    文章

    595

    瀏覽量

    27510
  • 二叉樹
    +關注

    關注

    0

    文章

    74

    瀏覽量

    12373
收藏 人收藏

    評論

    相關推薦

    基于二叉樹的時序電路測試序列設計

    為了實現時序電路狀態驗證和故障檢測,需要事先設計一個輸入測試序列?;?b class='flag-5'>二叉樹節點和樹枝的特性,建立時序電路狀態二叉樹,按照電路二叉樹節點(狀態)與樹枝(輸入)的層次邏輯
    發表于 07-12 13:57 ?0次下載
    基于<b class='flag-5'>二叉樹</b>的時序電路測試序列設計

    二叉樹層次遍歷算法的驗證

    實現二叉樹的層次遍歷算法,并對用”A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”創建的二叉樹進行測試。
    發表于 11-28 01:05 ?2119次閱讀
    <b class='flag-5'>二叉樹</b>層次遍歷算法的驗證

    二叉樹,一種基礎的數據結構類型

    然后我們再定義一棵深度也為 3 的二叉樹,該二叉樹的 n 個結點(n≤7),當從 1 到 n 的每個結點都與上圖中的編號結點一一對應時,這二叉樹就稱為完全二叉樹。
    的頭像 發表于 04-13 10:48 ?4410次閱讀
    <b class='flag-5'>二叉樹</b>,一種基礎的數據結構類型

    詳解電源二叉樹到底是什么

    作為數據結構的基礎,分很多種,像 AVL 、紅黑二叉搜索....今天我想分享的是關于二叉樹
    的頭像 發表于 06-06 15:05 ?1w次閱讀
    詳解電源<b class='flag-5'>二叉樹</b>到底是什么

    C語言二叉樹代碼免費下載

    本文檔的主要內容詳細介紹的是C語言二叉樹代碼免費下載。
    發表于 08-27 08:00 ?1次下載

    紅黑(Red Black Tree)是一種自平衡的二叉搜索

    平衡(Balance):就是當結點數量固定時,左右子樹的高度越接近,這棵二叉樹越平衡(高度越低)。而最理想的平衡就是完全二叉樹/滿二叉樹,高度最小的二叉樹。
    的頭像 發表于 07-01 15:05 ?5799次閱讀
    紅黑<b class='flag-5'>樹</b>(Red Black Tree)是一種自平衡的<b class='flag-5'>二叉</b>搜索<b class='flag-5'>樹</b>

    二叉樹操作的相關知識和代碼詳解

    是數據結構中的重中之重,尤其以各類二叉樹為學習的難點。在面試環節中,二叉樹也是必考的模塊。本文主要講二叉樹操作的相關知識,梳理面試常考的內容。請大家跟隨小編一起來復習吧。 本篇針對面
    的頭像 發表于 12-12 11:04 ?2088次閱讀
    <b class='flag-5'>二叉樹</b>操作的相關知識和代碼詳解

    二叉樹的前序遍歷非遞歸實現

    我們之前說了二叉樹基礎及二叉的幾種遍歷方式及練習題,今天我們來看一下二叉樹的前序遍歷非遞歸實現。 前序遍歷的順序是, 對于中的某節點,先遍歷該節點,然后再遍歷其左子樹,最后遍歷其右子
    的頭像 發表于 05-28 13:59 ?2000次閱讀

    二叉排序樹AVL如何實現動態平衡

    ? 什么是AVL 大家好,我是bigsai,好久不見,甚是想念,今天給大家講講AVL。 對于這種數據結構,想必大家也已經不再陌生,我們簡單回顧一下。 在的種類中,通常分成
    的頭像 發表于 10-28 17:02 ?1904次閱讀
    <b class='flag-5'>二叉排序樹</b>AVL如何實現動態平衡

    C語言數據結構:什么是二叉樹?

    完全二叉樹:完全二叉樹是效率很高的數據結構。對于深度為K,有n個節點的二叉樹,當且僅當每一個節點都與深度為K的滿二叉樹中編號從1至n的節點一一對應時,稱為完全
    的頭像 發表于 04-21 16:20 ?2698次閱讀

    怎么就能構造成二叉樹呢?

    一直跟著公眾號學算法的錄友 應該知道,我在二叉樹:構造二叉樹登場!,已經講過,只有 中序與后序 和 中序和前序 可以確定一顆唯一的二叉樹。前序和后序是不能確定唯一的二叉樹的。
    的頭像 發表于 07-14 11:20 ?1655次閱讀

    使用C語言代碼實現平衡二叉樹

    這篇博客主要總結平衡二叉樹,所以,二叉排序樹知識不會提及,但是會用到。
    的頭像 發表于 09-21 11:00 ?1154次閱讀

    二叉樹的代碼實現

    二叉樹的主要操作有遍歷,例如有先序遍歷、中序遍歷、后序遍歷。在遍歷之前,就是創建一棵二叉樹,當然,還需要有刪除二叉樹的算法。
    的頭像 發表于 01-18 10:41 ?1275次閱讀
    <b class='flag-5'>二叉樹</b>的代碼實現

    C++構建并復制二叉樹

    使用C++構建一個二叉樹并復制、輸出。
    的頭像 發表于 01-10 15:17 ?1077次閱讀
    C++構建并復制<b class='flag-5'>二叉樹</b>

    C++自定義二叉樹并輸出二叉樹圖形

    使用C++構建一個二叉樹并輸出。
    的頭像 發表于 01-10 16:29 ?1809次閱讀
    C++自定義<b class='flag-5'>二叉樹</b>并輸出<b class='flag-5'>二叉樹</b>圖形
    百家乐官网任你博娱乐场| 澳门百家乐官网游戏玩法| 百家乐单跳打法| 大发888下载17| 澳门百家乐官网一把决战输赢| 百家乐视频软件下载| 网上棋牌赌博| 百家乐官网怎样玩的| 水果机规律| 网上的百家乐官网是假的吗| 百家乐策略介绍| 百家乐官网智能投注系统| 威尼斯人娱乐城官方网址| 百家乐官网21点| 百家乐博百家乐| 洛隆县| 百家乐机器手怎么做弊| 最好的网上真人赌博| 百家乐视频游戏网址| 贵溪市| 百家乐试玩1000元| 如何玩百家乐官网游戏| 大发888奖金| 百家乐官网送钱平台| 卡卡湾网上娱乐| 澳门百家乐经历| 百家乐官网咋个玩的| 百家乐哪里可以玩| 至尊百家乐官网奇热网| 大发888论坛| 金世豪百家乐官网的玩法技巧和规则 | 百家乐官网赌场怎么玩| 全讯网768866| 星期8百家乐官网的玩法技巧和规则| 娱乐城送现金| 百家乐群号| 澳门玩百家乐官网赢1000万| 永利高a2| 游戏百家乐押发| 百家乐官网怎样玩才能赢| 威尼斯人娱乐网反水|