簡體   English   中英

C中鏈表的問題

[英]Problems with Linked List in C

我是C的新手,我正在為一個項目開發一個XOR鏈表。 我已完成大部分代碼,但我似乎無法使列表的刪除功能正常工作。 它似乎能夠刪除一些數字,但不能刪除傳遞給函數的任何數字。 任何有C經驗的人都可以看看,並可能指出我哪里出錯了? 我一直在研究這個問題並且沒有太多運氣而且我已經開始了3次以上:(非常感謝任何幫助。謝謝。你可以在這里看到我的第一次代碼嘗試。我只能發布一個鏈接,所以如果你想看到我的第二次嘗試,請告訴我,我可以通過電子郵件發送給你或者其他什么。謝謝你的時間。

#include <stdio.h>
#include <stdlib.h>
#include "rndm.h"

struct node {
       int data;
       unsigned long link;
};
struct node *head, *tail, *currN, *prevN, *nextN, *tmp;

void insert(struct node **headN, struct node **tailN, int n);
void delete(struct node **headN, struct node **tailN, int n);
void list(struct node *head, int i);
void nextNode();
void previNode();

//============================================================

void insert(struct node **headN, struct node **tailN, int numN) {
     struct node *newnode = malloc(sizeof(struct node));
     newnode->link =(unsigned long)(*headN);
     newnode->data = numN;

     //if empty list
     if (*headN == NULL){
          *headN = newnode;
          currN = *headN;
          (*headN)->link = 0;
     } else if ((*headN)->link == (unsigned long)NULL){
           if (numN <= (*headN)->data){
                newnode->link = (unsigned long) *headN;
                (*headN)->link = (unsigned long) newnode;
                tail = *headN;
                *headN = newnode;
                nextN = tail;
                prevN = NULL;
            } else {
                newnode->link = (unsigned long) *headN;
                (*headN)->link = (unsigned long) newnode;
                tail = newnode;
                nextN = NULL;
                currN = tail;
                prevN = *headN;
              }
     } else { 
          currN = *headN;
          prevN = NULL;
          nextN = (struct node *)(currN->link ^ (unsigned long) prevN);
          if (numN > tail->data){
               while (currN!=tail){
                     nextNode();
               }
               newnode->link = (unsigned long) currN;
               currN->link = (unsigned long) newnode ^ (unsigned long) prevN;
               tail = newnode;
          } else if (numN < head->data){
               currN->link = (unsigned long) newnode ^ (unsigned long) nextN;
               newnode->link = (unsigned long) currN;
               *headN = newnode;
               nextN = currN;
               currN = *headN;
          } else {
               while (numN > currN->data){
                     nextNode();
               }
               newnode->link = (unsigned long) prevN ^ (unsigned long) currN;
               prevN->link ^= (unsigned long) currN ^ (unsigned long) newnode;
               currN->link ^= (unsigned long) prevN ^ (unsigned long) newnode;
          }
     }
}  

void delete(struct node **headN, struct node **tailN, int numD){

     struct node *prevN = NULL;
     struct node *currN = *headN;

     while ( currN != NULL )
    {
        struct node *nextN = (struct node *) (currN->link ^ (unsigned long)prevN);  
        //if the number is found, then delete it
        if (currN->data == numD)
        {
          if(prevN) 
                  {
                     prevN->link ^= (unsigned long)currN ^ (unsigned long)nextN;
              }
                  else 
                     *headN = nextN;
              if(nextN) 
                  {
                     nextN->link ^= (unsigned long)currN ^ (unsigned long)prevN;
                  } 
                  else 
                     *tailN = prevN;
          free(currN);
          break;
        }
            prevN = currN;
        currN = nextN;
    }
}

void list(struct node *head, int i){

    if(i == 0){ 
     currN = head;
     prevN = NULL;
     int count = 1;
     nextN = (struct node *) (currN->link ^ (unsigned long) prevN);
     printf("Linked List in ascending order\n");
     while(currN!=NULL){
          if(count <= 10){
               printf("%-5d", currN->data);
               nextNode();
               count++;
          } 
          else{
               printf("\n");
               count = 1;
          }
     }
    }
     printf("\n\n"); 

    if(i == 1){ 
     printf("Linked List in descending order\n");
     currN = tail;
     int count2 = 1;
     prevN = (struct node *) currN->link;
     nextN = NULL;
     while (currN!=NULL){
         if(count2 <= 10){
              printf("%-5d", currN->data);
              previNode();
              count2++;

          }else{
              printf("\n");
              count2 = 1;
          }
     } 
    }   
    printf("\n");         
}

void nextNode(){
    nextN = (struct node *) (currN->link ^ (unsigned long) prevN);
    prevN = currN;
    currN = nextN;
}

void previNode(){
    prevN = (struct node *) (currN->link ^ (unsigned long) nextN);
    nextN = currN;
    currN = prevN;      
}

int main(){

    int i, num;
    float seed;
    head = NULL; tail = NULL; currN = NULL; prevN = NULL; nextN = NULL;

    init_seed(1234567);
    set_range(1,9999);
    //inserting data into the linked list
    for ( i=0; i<100; ++i){
        num = rndm();
        insert( &head, &tail, num );
    }

    list((struct node*)head, 0);
    //delete((struct node**)head, (struct node**)tail, 45);
    //delete((struct node**)head, (struct node**)tail, 4040);
    //delete((struct node**)head, (struct node**)tail, 9769);
    list((struct node*)head, 1);


    return 0;
}

看起來你在互聯網上拿了一些代碼並試圖使用它。

代碼工作得很好,你只是不知道指針是什么。

你在做:

delete((struct node**)head, (struct node**)tail, 45);

以下是變量headtail的定義:

struct node {
  int data;
  unsigned long link;
};
struct node *head, *tail, *currN, *prevN, *nextN, *tmp;

delete()函數的原型是void delete(struct node **headN, struct node **tailN, int numD);

“哦編譯器要求struct node ** ,讓我們投吧”。 這不是它的工作原理。

嘗試這個:

delete(&head, &tail, 45);

關於您的代碼的說明:

node.link不應該是unsigned long ,因為它假定您編譯器/平台的特性。

編輯:也許我錯過了XOR鏈表,討論。

編輯2 :(由@Matthew Flaschen建議)使用intptr_t使您的代碼更具可移植性。

看看delete函數讓我想知道這個指針操作,順便說一句,你使用的是參數地址,所以它應該是delete(&head, &tail, 45);

從那繼續......

void delete(struct node **headN, struct node **tailN, int numD)
{
   struct node *prevN = NULL;
   struct node *currN = *headN; 
   struct node *tempNode = NULL;

   while ( currN != NULL )
   {
      struct node *nextN = (struct node *) (currN->link ^ (unsigned long)prevN);  
      //if the number is found, then delete it
      if (currN->data == numD)
      {
          if(prevN)
             prevN->link ^= (unsigned long)currN ^ (unsigned long)nextN;
          else 
             *headN = nextN;
          if(nextN)
             nextN->link ^= (unsigned long)currN ^ (unsigned long)prevN;
          else
             *tailN = prevN;
          /* Sanity check here...you could be screwing up the list 
          ** by calling free(currN)
          */
          tempNode = currN;
          free(tempNode);
          /* free(currN); <-- That could be misleading... */
          break;
       }
       prevN = currN;
       currN = nextN;
   }
}

對代碼的修改是為了確保currN是一致的,用眼睛看指針操作,這可能是有問題的,因為列表最終會因為在currNfreecurrN ...只是為了安全。 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM