打印树结果,分割错误,插入树

时间:2015-02-24 20:54:07

标签: c

这里是代码,我用一个例子来运行它,但是当它出现时

比较我不明白什么是错的? ,提前感谢

任何帮助。我需要正确打印字典文本(插入,打印),还不能提出解决方案,我的意思是使用字典数据结构。

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

typedef struct Node_s {
  char *element;
  struct Node_s *left, *right;
} Node;

typedef struct {
 Node *head;
} Table;
//Table *initialize();
//Node *createNode(const char *element);

Table *initialize() {
  Table *tb = malloc(sizeof(Table)*1000);
  tb->head = NULL;
  return tb;
}
Node *createNode( char * element ) {
  Node *temp  = malloc(sizeof(temp));
  temp->element  = element ;
  temp->left = temp->right = NULL;
  return temp;
}

 void insert(Table *temp,  char *element) {
 Node *nd = createNode(element);
 Table * place = NULL;
 Node *new = NULL;
 int cmp = 0; 
 if(temp->head == NULL) {
    temp->head= nd;
    printf("empty ! \n");
    return;
 }
 else {
    Table *current = temp;
    while (current!=NULL) {
        cmp = strcmp(current->head->element,element);
        if(cmp < 0)  { 
            current->head= current->head->left;
        }
        else if(cmp > 0)  { 
            current->head = current->head->right;
        }

  } //while
  place = current;
  new = nd;
  if(cmp > 0 ) {
    place->head->right = new ;
  }
  else if(cmp <0 ) { 
    place->head->left = new;
  }
 }
 }   
 void print_table(Table *temp) {
   if(temp!=NULL || !temp->head) return;
    print_table(temp->head->left);
    printf("%s   \n",temp->head->element);
    print_table(temp->head->right);      
 }
 int main () {
  Node * nd = NULL;
  //nd->element = "key";
  // nd = createNode("key");
  Table *tb  = initialize();
  //tb->head = createNode("key");
  //tb->head = createNode("key");
  insert(tb, "table element1");
  insert(tb, "table element2");
  insert(tb, "table element2");
  //nd = createNode("key1");
  // print_table(t);
  //printf("%s \n",nd->element);
  print_table(tb);
  // printf("%s \n",tb->head->element); 
  free(nd);
  return 0;
 }

5 个答案:

答案 0 :(得分:1)

这里存在很多潜在的错误,但您的主要问题在于createNode的以下行:

Node *temp  = malloc(sizeof(temp));

这里你正在做一个sizeof(temp),temp是一个指针。这意味着您只为指针分配足够的内存(通常为8个字节)。因此,在使用堆分配结构的左/右成员时,您正在编写分配内存之外的内容。修复:

Node *temp  = malloc(sizeof(Node));

// EXTRA: I also recommend that you verify that the allocation was successful
if (temp) {
    temp->element  = element ;
    temp->left = temp->right = NULL;
}

return temp;

在printTable中,您还应验证temp本身不是NULL,因为您传递的函数参数可能为NULL:

if(!temp || !temp->head) return;

此外,删除main末尾的free(nd);,因为在未分配的堆内存上调用free()会破坏堆,并且通常会导致段错误。

答案 1 :(得分:1)

您的打印方法在到达左侧的最后一个节点时崩溃,因为它会调用print_table(NULL),因为左侧没有其他内容。之后,当它执行行

if(!temp->head) return;

由于temp为NULL,您会收到内存访问冲突,还应检查temp本身是否为NULL。

if( !temp || !temp->head ) return;

那应该解决你的问题。

答案 2 :(得分:1)

第二个问题是第二次拨打insert

while (current != NULL) {
    cmp = strcmp(current->head->element, element);  // this line

您没有检查current->head本身是否为NULL。根据您实施的内容,您使用head作为哨兵,因此它可以为NULL。但是,您的搜索循环完全忘记了这种情况,并假设head永远不会为NULL。

你的循环看起来并不正确。你遍历左边,所以如果左分支&#34;用完了将会发生的事情。 (就像你第二次打电话给insert时那样)?

此外,您的insert函数存在内存泄漏。您可能在此处分配2个新节点:

Node *nd = createNode(element);

在这里:

new = createNode(element);

只有一个存储而另一个存在泄漏。

另一个问题是,如果两个项目相同,那么您的树在while循环中不执行任何操作。两个相等的项会导致无限循环:

while (current!=NULL) 
{
     cmp = strcmp(current->head->element,element);
     if(cmp < 0)  
         current->head= current->head->left;
     else if(cmp > 0)   
         current->head = current->head->right;
     else 
         printf("these are equal   ! \n");  // but we don't do anything with current!
 } 

如果目标是没有重复项,那么如果找到重复项,则应退出此函数。如果目标是存储重复项,则只测试< 0,其他任何内容都会在正确的分支上进行。

答案 3 :(得分:0)

This might be what you are looking for.
It handles a doubly linked list

error checking is added
removed undesirable/unnecessary typedef's from struct definitions

corrected the logic to link in new nodes

avoided recursion in the printing of the linked list

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


struct Node 
{
  char *element;
  struct Node *left;
  struct Node *right;
}; 


// define the head pointer for the linked list
struct Node *head = NULL;




// struct Node *createNode(const char *element);




struct Node *createNode( char * element ) 
{
    struct Node *pNewNode  = NULL;

    if( NULL == (pNewNode = malloc(sizeof(struct Node)) ) )
    { // then, malloc failed
        perror( "malloc for new node failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    pNewNode->element  = element ; // copies a char pointer
    pNewNode->left  = NULL;
    pNewNode->right = NULL;
    return pNewNode;
} // end function: createNode


void insert(char *element) 
{
    int cmp = 0; 
    // get ptr to first node in list
    struct Node *pCurrentNode = head;

    // create the node to be inserted into linked list
    struct Node *pNewNode = createNode(element);


    if (pCurrentNode == NULL) 
    { // then list empty
        head = pNewNode;
        printf("added first node\n");
        return;
    }

    // implied else, not first node

    while (pCurrentNode->right) 
    {
        cmp = strcmp(pCurrentNode->element,element);

        if(cmp < 0)  
        { 
            // insert new node before current node
            pNewNode->right = pCurrentNode;
            pNewNode->left  = pCurrentNode->left;
            pCurrentNode->left = pNewNode;
            (pNewNode->left)->right = pNewNode;
        }

        else if(cmp > 0)  
        { 
            // step to next node
            pCurrentNode = pCurrentNode->right;
        } // end if

        // note: if data same, don't insert new node
    } //while


    if( pCurrentNode->right == NULL )
    { // then, reached end of list
        // append new node to end of list
        pNewNode->left = pCurrentNode;
        pNewNode->right = NULL;
        pCurrentNode->right = pNewNode;
    } // end if
}  // end function: insert


void print_table() 
{
     struct Node *pCurrentNode = head;

     if( pCurrentNode == NULL ) return;

     // implied else, list not empty

     while( pCurrentNode )
     {
         printf("%s   \n",pCurrentNode->element);
         pCurrentNode = pCurrentNode->right;
    } // end while     
} // end function: print_table


void cleanup()
{
    struct Node *pCurrentNode = head;

    while( pCurrentNode )
    {
        pCurrentNode = pCurrentNode->right;
        free( pCurrentNode->left );
    }
} // end function: cleanup


int main () 
{   
    // exercise the insert function
    insert("table element1"); // append first element
    insert("table element2"); // append second element
    insert("table element4"); // append third element
    insert("table element3"); // insert forth element
    insert("table element3"); // duplicate within list
    insert("table element4"); // duplicate at end of list

    print_table();

    cleanup();
    return 0;
} // end function: main

答案 4 :(得分:0)

我尝试了不同的实现,它编译并运行,它不允许重复。

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

#define ELEMENT_SIZE 1024

typedef struct Node_s
{
    char element[ELEMENT_SIZE];
    struct Node_s *left, *right;
} Node;


Node * createNode(char *element)
{
    Node *node = malloc(sizeof(Node));
    node->left = NULL;
    node->right = NULL;
    memcpy(node->element, element, ELEMENT_SIZE);
    return node;
}

void free_node(Node *node)
{
    if(!node)
        return;
    free_node(node->left);
    free_node(node->right);
    free(node);
}

Node * insert(Node **head_ptr,  char *element)
{
    Node *head = *head_ptr;
    if(head == NULL){
        Node *node = createNode(element);
        head = node;
        *head_ptr = node;
        return node;
    }else{
        int comp = strcmp(head->element, element);
        if(comp < 0){
            // go left
            if(head->left == NULL){
                // set element to be temp left
                Node *node = createNode(element);
                head->left = node;
                return node;
            }else{
                return insert(&head->left, element);
            }

        }else if(comp > 0){
            // go right
            if(head->right == NULL){
                // set element to be temp left
                Node *node = createNode(element);
                head->right = node;
                return node;
            }else{
                return insert(&head->right, element);
            }
        }else{
            // element exists
            printf("Element \"%s\" already exists\n", element);
            return NULL;
        }
    }
}

void print_table(Node *temp)
{
    if(!temp)
        return;
    printf("%s   \n",temp->element);
    print_table(temp->left);
    print_table(temp->right);
}

int main ()
{
    Node *nd = NULL;
    printf("Address of nd is %p\n", &nd);

    Node *n1 = insert(&nd, "table element 1");
    n1 = insert(&nd, "table element 2");
    n1 = insert(&nd, "table element 3");

    n1 = insert(&nd, "element 1");
    n1 = insert(&nd, "element 2");
    n1 = insert(&nd, "element 3");

    n1 = insert(&nd, "alternative 1");
    n1 = insert(&nd, "alternative 2");
    n1 = insert(&nd, "alternative 3");

    n1 = insert(&nd, "alternative 1");
    n1 = insert(&nd, "alternative 2");
    n1 = insert(&nd, "alternative 3");

    print_table(nd);

    free_node(nd);
    return 0;
}