[英]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);
以下是變量head
和tail
的定義:
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
是一致的,用眼睛看指針操作,這可能是有問題的,因為列表最終會因為在currN
上free
而currN
...只是為了安全。 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.