如果元素在中间,则双向链表插入排序不起作用

时间:2013-11-05 13:45:22

标签: c

我的问题是当我插入数字时它有效但是如果我想在中间插入它会插入但不打印下一个节点我不知道它是删除它们还是无法访问它们。

struct node {
    int data ;
    struct node *prev;
    struct node *next;
};

struct node* head = NULL;

这是有问题的函数插入。

void insert(int key) {
    struct node *pred=head, *succ;
    struct node *temp2, *temp;
    if (head==NULL) {
        head = (struct node *) malloc(sizeof(struct node));
        head->data = key;
        head->prev = NULL;
        head->next = NULL;
    } else {
        temp2 = (struct node*) malloc(sizeof(struct node));
        temp2->data =  key;
        temp = head;
        while(temp->next!=NULL && temp->next->data < key) {
            pred= temp->next;
            temp = temp->next;
        }
        printf("******pred : %d \n",pred->data);
        //printf("******temp-next %d \n",temp->next->data);
        if (temp->data < key) {
            temp->next = temp->next->next;
            temp->next = temp2;
            temp2->prev = temp;
            temp2->next = pred->next->next;
        } else {     
            //temp2->next= temp;
            //temp->prev = NULL; 
            temp2->next = head;
            //head->prev = temp2;
            head = temp2;
            printf("**** temp : %d",temp->data);
            printf("**** temp2 : %d",temp2->data);
            printf("here\n");
            //temp = temp2 ->prev;
            //temp->prev = NULL;        
        }           
    }
}

4 个答案:

答案 0 :(得分:0)

我建议你修改变量temp1,2的名字。这使得对代码的理解变得复杂 在while()循环中,存在具有相同值的pred和temp变量。那么为什么不只是删除其中一个?
在while()循环之后有一个值的检查 - 但是while()循环已经在循环遍历项目时检查了这个条件的项目临时值。所以这个检查是错误的。
现在你已经知道项目“temp”小于key,但是下一个项目,如果它不是NULL则更大。所以你必须检查它是否为NULL。
如果它是NULL,那么你必须在列表的末尾添加新项目。
如果它不是NULL,那么你必须在当前项目“temp”之后和“temp-&gt”之前添加项目;下一个“因为”temp-&gt; next“已经大于当前项目”temp“和新项目。

在if语句的情况下使用代码,然后header不是NULL(为了清晰而重命名了一些变量):

{   
    assert(head != NULL); // head not NULL already
    newItem = (struct node*) malloc(sizeof(struct node));
    newItem->data =  key;
    currItem = head;

    while(currItem->next!=NULL && currItem->next->data < key){
        currItem = currItem->next;}

    if(currItem->next == NULL){ // append new item to the end of list
        currItem->next = newItem;
    }               
    else{ // insert somewhere in the middle (next item key is greater than current key)
        newItem->next = curr->next;
        currItem->next = newItem;
    }           
}

答案 1 :(得分:0)

中间代码中的插入(发布的代码示例中的最后一个if语句)应该更好地工作:

    if (temp->data < key) {
        // Insert in the middle
        temp->next = temp2;
        temp2->prev = temp;
        temp2->next = pred->next->next;
        temp2->next->prev = temp2;       // Added
    } else {     
        // Insert last                   // Changed entire block
        temp2->prev= temp;     
        temp->next = temp2; 
        temp2->next = null;
    }           

答案 2 :(得分:0)

对于双向链表,保持tail将是对称的。 没有它,我会这样做。

整个插页:

struct node* prev = NULL;
struct node* ptr;
for (ptr = head; ptr != NULL && key < ptr->data; ptr = ptr->next) {
    prev = ptr;
}

struct node* baby = (struct node *) malloc(sizeof(struct node));
baby->data = key;
baby->prev = prev;
baby->next = ptr;
if (prev != null) {
    prev->next = baby; // Link in from previous
}
if (ptr != null) {
    ptr->prev = baby; // Link in from next
}
if (head == NULL) {
    head = baby;
}

答案 3 :(得分:0)

重新安排了一下:

temp = calloc(1, sizeof(struct node)); // 0's node
temp->data=key;  

if ( head == NULL ) // empty
{
  temp = head; // done
}
else if ( head->data < key ) // first element already larger
{
  temp->next = head;
  head->prev = temp;
  head = temp;
}
else // find larger key
{
  struct node *pred = NULL; // technically head->prev
  struct node *succ = head;      

  while( succ != NULL && succ->data < key )
  { 
    pred = succ;  // previous
    succ = succ->next;
  } 

  // went to end of list, so append to end
  if ( succ == NULL )
  {
    temp->prev = pred;
    pred->next = temp;
  }
  else // found one larger
  {
    temp->next = succ;
    temp->prev = succ->prev;
  }
}