C 中链表的问题

发布于 2024-08-24 17:54:47 字数 5581 浏览 3 评论 0原文

我是 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;
}

I am new to C and I am working on an XOR linked list for a project. I have most of the code done, but I can't seem to get the delete function of the list to work properly. It seems able to delete some numbers, but not any number you pass into the function. Could anyone experienced with C take a look and possibly point out where I went wrong? I have been working on this for a while now and have not had much luck and I have started over 3 times :( Any help is much appreciated. Thank you. You can see my first attempt of code here. I can only post one link, so if you would like to see my second attempt, just tell me so and I can email it to you or something. Thank you for your time.

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

注定孤独终老 2024-08-31 17:54:47

看来您在互联网上获取了一些代码并尝试使用它。

代码运行得很好,只是你不知道指针是什么。

您正在做的事情:

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);

It looks like you took some code on the internet and tried to use it.

The code works just fine, you just don't know what a pointer is.

You're doing:

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

And here are the definitions of the variables head and tail:

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

The prototype for the delete() function is void delete(struct node **headN, struct node **tailN, int numD);

"Oh the compiler is asking for struct node **, let's cast it". That's not how it works.

Try this:

delete(&head, &tail, 45);
怪我入戏太深 2024-08-31 17:54:47

关于您的代码的注释:

node.link 不应该是 unsigned long 它,因为这假定了您的编译器/平台的特征。

编辑:也许我错过了 XOR 链接列表的讨论。

编辑2:(按照@Matthew Flaschen的建议)使用intptr_t使您的代码更加可移植。

A note about your code:

The node.link should not be a unsigned long it since this assumes characteristics of you compiler/platform.

EDIT: Maybe I missed out on the XOR linked list, discussion.

EDIT 2: (as suggested by @Matthew Flaschen) use intptr_t to make your code more portable.

来世叙缘 2024-08-31 17:54:47

看看 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 是一致的,用眼睛观察指针操作,这可能是有问题的,因为为了安全起见,在 currN 上执行 free 可能会导致列表最终被破坏...

Looking at the delete function makes me wonder about this pointer manipulation, by the way, you are using address-of parameters so really it should be delete(&head, &tail, 45);

moving on from that....

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;
   }
}

That amendment to the code is to ensure that currN is consistent, looking at with eyes on the pointer manipulation, that could be questionable, as the list could end up broken by doing a free on the currN...just to be safe...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文