informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
pohon adalah anonlinier Struktur data, yang merupakan sekumpulan hubungan hierarki yang terdiri dari n (n>=0) node terbatas.BundelDisebut pohon karena bentuknya seperti pohon terbalik, artinya akarnya mengarah ke atas dan daunnya mengarah ke bawah.
- Node root: Node root tidak memiliki node pendahulunya.
- Kecuali simpul akar, simpul-simpul yang tersisa dibagi menjadi sub-pohon dengan struktur yang mirip dengan pohon. Node akar dari setiap subpohon mempunyai satu dan hanya satu pendahulu, dan dapat mempunyai 0 atau lebih penerus.
- Oleh karena itu, pohon itu adalahdefinisi rekursifdari.
Struktur pohon lebih rumit daripada tabel linier, dan lebih sulit untuk menyimpan dan merepresentasikannya.Penting untuk menyimpan rentang nilai dan hubungan antara node dan node., sebenarnya ada banyak cara untuk merepresentasikan pohon, seperti:Notasi orang tua, notasi anak, notasi orang tua anak, dan notasi saudara anakTunggu.
Dalam proses memperkenalkan struktur penyimpanan berikut, kami mengambil pohon berikut sebagai contoh.
Kami berasumsi bahwa simpul-simpul pohon disimpan dalam sekumpulan ruang yang berkesinambungan, dan pada waktu yang samaDi setiap node, dipasang indikator untuk menunjukkan posisi node induknya dalam daftar tertaut. . Dengan kata lain, selain mengetahui siapa node tersebut, setiap node juga mengetahui keberadaan induknya.
Diantaranya, data adalah bidang data, yang menyimpan informasi data dari node. Dan induk adalah bidang penunjuk yang menyimpan subskrip induk simpul dalam larik.
Berikut ini adalah kode definisi struktur simpul untuk representasi induk kita.
/*树的双亲表示法结点结构定义*/
#define MAX_TREE_SIZE 100
typedef int TElemType; //树结点的数据类型,目前暂定为整型
/*结点结构*/
typedef struct TreeNode
{
TElemType data; //结点数据
int parent; //双亲位置
}TreeNode;
/*树结构*/
typedef struct
{
TreeNode nodes[MAX_TREE_SIZE]; //结点数组
int r, n; //根的位置和结点数
}PTree;
Dengan struktur penyimpanan seperti itu, kita dapat dengan mudah menemukan node induknya sesuai dengan penunjuk induk dari node yang digunakanKompleksitas waktu adalah 0(1) , hingga induknya -1, menandakan bahwa akar simpul pohon telah ditemukan. Namun jika kita ingin mengetahui apa itu anak dari node tersebut, maaf silahkan melintasi seluruh strukturnya.
Baru saja kita mempelajari struktur penyimpanan pohon dari sudut pandang orang tua dan sudut pandang anak. Bagaimana jika kita melihat saudara dari simpul pohon? Tentu saja, untuk struktur hierarki seperti pohon, kita hanya mempelajarinya saudara dari simpul tersebut. Hal ini tidak mungkin. Setelah observasi, kami menemukan bahwa untuk pohon mana pun, anak pertama dari simpul tersebut adalah unik jika ada, dan saudara kanannya juga unik jika ada. Oleh karena itu, kami menetapkan dua pointer, menunjuk ke anak pertama dari node dan saudara kanan dari node.
/*树的孩子兄弟表示法结构定义*/
typedef struct TreeNode
{
TElemtype data;
struct TreeNode *firstchild, *rightsib;
} TreeNode,* pTreeNode;
Pohon biner adalah kumpulan node berhingga, yaitu:
- atau kosong
- Ini terdiri dari sebuah simpul akar ditambah dua pohon biner, juga dikenal sebagai subpohon kiri dan subpohon kanan.
Seperti yang terlihat dari gambar di atas:
- Tidak ada simpul dengan derajat lebih besar dari 2 dalam pohon biner
- Subpohon dari pohon biner dapat dibagi menjadi subpohon kiri dan kanan, dan urutannya tidak dapat dibalik, sehingga pohon binernya adalahpohon yang dipesan
Catatan: Setiap pohon biner terdiri dari situasi berikut:
Pohon biner umumnya dapat disimpan menggunakan dua struktur:Struktur berurutan, struktur rantai.
Pohon biner biasa tidak cocok untuk disimpan dalam susunan karena mungkin terdapat banyak ruang yang terbuang.DanPohon biner lengkap lebih cocok untuk penyimpanan struktur sekuensial .Kenyataannya, kita biasanyaHeap (pohon biner) menggunakan array struktur berurutan untuk menyimpan, perlu dicatat bahwa heap di sini dan heap di ruang alamat proses virtual sistem operasi adalah dua hal yang berbeda. Yang pertama adalah struktur data, dan yang lainnya adalah segmentasi area yang mengelola memori dalam sistem operasi.
Untuk implementasi dan penerapan spesifik, silakan lihat:[Struktur Data] 08. Aplikasi heap dan heap
Cara paling sederhana untuk mempelajari struktur pohon biner adalah dengan melintasinya.yang disebutPenjelajahan pohon biner (Traversal) adalah melakukan operasi terkait pada node dalam pohon biner secara berurutan sesuai aturan tertentu, dan setiap node hanya dioperasikan satu kali . Operasi yang dilakukan dengan mengakses node bergantung pada masalah aplikasi spesifik. Traversal adalah salah satu operasi terpenting pada pohon biner dan juga merupakan dasar untuk operasi lain pada pohon biner.
//根 左子树 右子树
void PrevOrder(pTreeNode root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
printf("%d ", root->val);
PrevOrder(root->left);
PrevOrder(root->right);
}
Gambar di bawah menunjukkan proses rekursif:
//左子树 根 右子树
void InOrder(pTreeNode root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
InOrder(root->left);
printf("%d ", root->val);
InOrder(root->right);
}
Berikut ini adalah proses rekursifnya:
//左子树 右子树 根
void PostOrder(pTreeNode root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->val);
}
Berikut ini adalah proses rekursifnya:
Penjelajahan tingkat pesanan: Selain penjelajahan pesanan sebelumnya, penjelajahan dalam pesanan, dan penjelajahan pasca pesanan, penjelajahan tingkat pesanan juga dapat dilakukan pada pohon biner. Asumsikan bahwa jumlah level dari simpul akar pohon biner adalah 1. Penjelajahan urutan tingkat dimulai dari simpul akar dari pohon biner. Pertama, ia mengunjungi simpul akar pada tingkat pertama, kemudian mengunjungi simpul pada tingkat kedua tingkat dari kiri ke kanan, dan kemudian tingkat ketiga. Node lapisan, dan seterusnya,Proses mengunjungi node pohon selapis demi selapis dari atas ke bawah dan dari kiri ke kanan merupakan traversal urutan lapisan.。
Ilustrasi:
Di sini kita mengintervensi antrian untuk melakukan pre-order traversal dari pohon biner.
// 层序遍历
void LevelOrder(pTreeNode root)
{
Queue q;
QueueInit(&q);
if (root)
{
QueuePush(&q, root);
}
while (!QueueEmpty(&q))
{
pTreeNode front = QueueFront(&q);
QueuePop(&q);
if (front == NULL)
{
printf("NULL ");
}
else
{
printf("%d ", front->val);
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
}
QueueDestory(&q);
}
Untuk membuat dan menghancurkan pohon biner, kami menggunakanPenjelajahan pohon binerMisalnya.
//二叉树的创建
struct TreeNode* Creat(char* arr,int n,int* i)
{
if(*i<n&&arr[*i]=='#')
{
(*i)++;
return NULL;
}
TreeNode* newnode=(TreeNode*)malloc(sizeof(TreeNode));
newnode->left=NULL;
newnode->right=NULL;
newnode->val=arr[(*i)++];
newnode->left=Creat(arr,n,i);
newnode->right=Creat(arr,n,i);
return newnode;
}
//二叉树的销毁
void TreeDestroy(struct TreeNode* root)
{
if(root==NULL)
{
return;
}
TreeDestroy(root->left);
TreeDestroy(root->right);
free(root);
}
Semua operasi berikut dilakukan sesuai dengan gagasan traversal.
// 二叉树节点个数
int TreeSize(pTreeNode root)
{
if (root == NULL)
{
return 0;
}
return TreeSize(root->left) + TreeSize(root->right) + 1;
}
// 二叉树叶子节点个数
int TreeLeafSize(pTreeNode root)
{
if (root == NULL)
{
return 0;
}
if (root->left == NULL && root->right == NULL)
{
return 1;
}
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
// 二叉树第k层节点个数
int TreeLevelKSize(pTreeNode root, int k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return TreeLevelKSize(root->left, k - 1) + TreeLevelKSize(root->right, k - 1);
}
// 二叉树查找值为x的节点
pTreeNode TreeFind(pTreeNode root, TreeDataType x)
{
if (root == NULL)
{
return NULL;
}
//相等就返回
if (root->val == x)
return root;
//找左子树
pTreeNode left=TreeFind(root->left, x);
if (left)
{
return left;
}
//找右子树
pTreeNode right = TreeFind(root->right, x);
if (right)
{
return right;
}
//都没找到
return NULL;
}
//二叉树的高度
int TreeHeight(pTreeNode root)
{
if (root == NULL)
{
return 0;
}
int max_left = TreeHeight(root->left) ;
int max_right = TreeHeight(root->right);
return max_left > max_right ? max_left + 1 : max_right + 1;
}
//判断是否是完全二叉树
bool TreeComplete(pTreeNode root)
{
Queue q;
QueueInit(&q);
if (root)
{
QueuePush(&q, root);
}
while (!QueueEmpty(&q))
{
pTreeNode front = QueueFront(&q);
QueuePop(&q);
if (front == NULL)
{
break;
}
else
{
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
}
while (!QueueEmpty(&q))
{
pTreeNode front = QueueFront(&q);
QueuePop(&q);
if (front)
{
QueueDestory(&q);
return false;
}
}
QueueDestory(&q);
return true;
}