简体   繁体   English

C中仅使用指针的二叉树

[英]Binary tree in C using only pointers

I'm working on a homework assignment in C and I think that a binary search tree would be the best way to implement my solution. 我正在用C进行作业分配,我认为二进制搜索树将是实现我的解决方案的最佳方法。 The problem is we aren't allowed to define structs or any compound data types, so no 问题是我们不允许定义结构或任何复合数据类型,因此

struct TreeNode {
    struct TreeNode* parent;
    struct TreeNode* left;
    struct TreeNode* right;
    int key;
    int value;
}

or anything like that. 或类似的东西。

The tree will have to be entirely implemented with pointers, so I've been trying to define a number of macros to make navigating and editing the tree easier, such as this one to get a pointer to the parent of a node (where the pointers are void pointers): 该树将必须完全使用指针来实现,因此我一直在尝试定义一些宏,以使导航和编辑树更加容易,例如,该宏用于获取指向节点父节点的指针(其中的指针是无效的指针):

#define PARENT(ptr) *(void *)(ptr+ALIGNMENT)

The problem, of course, is that you can't dereference void pointers. 当然,问题在于您不能取消引用空指针。 My question is: if you have a void pointer to a location in memory where another void pointer is stored, how can you read that stored pointer. 我的问题是:如果您有一个空指针指向内存中另一个空指针存储的位置,那么如何读取该存储的指针。

Or if that's impossible, is there a better way to do this tree? 还是如果不可能,是否有更好的方法来做这棵树?

Represent the nodes as an array and use pointer arithmetic to access the left and right nodes of a given node. 将节点表示为数组,并使用指针算法访问给定节点的左节点和右节点。 For example, the numeric sequence 4, 3, 7, 1, 6 is stored in a binary tree: 例如,数字序列4、3、7、1、6存储在二叉树中:

     4
    / \ 
   3   7 
  / \ 
 1   6

if you choose to represent this tree using an array, the position of the left child of a node at position C is 2 * C and its right node is at 2 * C + 1 . 如果选择使用数组表示该树,则节点的左子节点在位置C位置为2 * C ,其右节点在2 * C + 1 In our example, the number 3 is at the second position. 在我们的示例中,数字3位于second位置。 Its left child is at 2 * 2 , ie at the fourth position and the right child is at 2 * 2 + 1 , ie at the fifth position: 它的左子节点在2 * 2 ,即在fourth位置,而右子节点在2 * 2 + 1 ,即在第五位置:

values:     4     3     7     1     6
positions: 1st   2nd   3rd   4th   5th 

The following sample code shows how to walk an array based binary tree. 以下示例代码显示了如何遍历基于数组的二叉树。 You can figure out how to insert new values into the tree (using the above formulas), how to dynamically grow the array, how to use pointer arithmetic to access child nodes etc: 您可以弄清楚如何将新值插入树中(使用上述公式),如何动态增长数组,如何使用指针算法访问子节点等:

#include <stdio.h>

#define ARRAY_SIZE 5
static int btree[ARRAY_SIZE];

static void fill_btree ();
static void walk_btree ();

int
main ()
{
  fill_btree ();
  walk_btree ();
  return 0;
}

static void 
fill_btree ()
{
  btree[0] = 4;
  btree[1] = 3;
  btree[2] = 7;
  btree[3] = 1;
  btree[4] = 6;
}

static int
pos (int i)
{
  return ((i + 1) * 2);
}

static void 
walk_btree ()
{
  int i;

  for (i = 0; i < ARRAY_SIZE; ++i)
    {
      int p = pos(i);
      int root = btree[i];
      int left = ((p - 1) < ARRAY_SIZE) ? btree[p-1] : 0;
      int right = (p < ARRAY_SIZE) ? btree[p] : 0;

      printf ("root: %d, left: %d, right: %d\n", root, left, right);
    }
}

Here is a way to handle your pointers. 这是一种处理指针的方法。 I didn't write your whole tree (you can do that), but here is a way to manage your pointer "structure" without using a real structure. 我没有写整个树(您可以这样做),但是这是一种无需使用实际结构即可管理指针“结构”的方法。 This doesn't build a tree for you, it just shows how you would create "faux" nodes and manage the pointers in memory. 这不会为您构建树,而只是显示您将如何创建“人造”节点并管理内存中的指针。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned int *newNode();

int main() {
  unsigned int *root;
  unsigned int *data;
  unsigned int *left, *right;
  unsigned int *nodeA, *A, *nodeB, *B;

  /* get a 12 byte root node */
  root = newNode();
  printf("root: %p\n", root);

  /* Setup root node.  Each is an offset unsigned into the 12 bytes in the faux node */
  data = root;
  left = root + 1;
  right = root + 2;

  /* create a NEW 12 byte child node and assign it to the root left child */
  nodeA = newNode();
  memcpy(left,&nodeA,sizeof(unsigned int));
  printf("NodeA ptr (left child root): %p\n", nodeA);

  /* create a NEW 12 byte child node and assign it to the root right child */
  nodeB = newNode();
  memcpy(right,&nodeB,sizeof(unsigned int));
  printf("NodeB ptr (right child root): %p\n", nodeB);

  /* what are my pointers? */
  A = (unsigned int *)*(root + 1); /* root left node is pointing to child nodeA */
  B = (unsigned int *)*(root + 2); /* root right node is pointing to child nodeB */

  printf("A: %p, B: %p\n", A, B);

  /*    
   * hopefully from this you can see the recursive nature of it and how    
   * you would build the tree using these pointer allocations and assignments    
   */    

  /*    
   * This is not meant to be a full working application.  I did not free any    
   * of these mallocs.  You have to free up your memory when the program     
   * finishes.  This was just to show how to go about making nodes    
   */ 

 return(0);
}

/* 
 * allocates 12 bytes to hold three unsigned integers, one to some data stream
 * one for the left node, one for the right node
 *
 * |--data--|--left--|--right--| (each block is a four byte unsigned int)
 *
 */
unsigned int *newNode() {
  /* Allocates 12 bytes to store 3 unsigned integer values */
  unsigned int *ptr = (unsigned int *)malloc(sizeof(unsigned int) * 3);
  memset(ptr,0,sizeof(unsigned int) * 3);
  return(ptr);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM