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;
}
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看来您在互联网上获取了一些代码并尝试使用它。
代码运行得很好,只是你不知道指针是什么。
您正在做的事情:
以下是变量
head
和tail
的定义:delete()
函数的原型是void delete(struct node **headN, struct node **tailN, int numD);
“哦,编译器要求
struct node **
,让我们转换它”。事情不是这样的。试试这个:
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:
And here are the definitions of the variables
head
andtail
:The prototype for the
delete()
function isvoid 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:
关于您的代码的注释:
node.link
不应该是unsigned long
它,因为这假定了您的编译器/平台的特征。编辑:也许我错过了 XOR 链接列表的讨论。
编辑2:(按照@Matthew Flaschen的建议)使用intptr_t使您的代码更加可移植。
A note about your code:
The
node.link
should not be aunsigned 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.
看看
delete
函数让我想知道这个指针操作,顺便说一句,你正在使用地址参数,所以它实际上应该是delete(&head, &tail, 45 );
从那开始......
对代码的修改是为了确保 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 bedelete(&head, &tail, 45);
moving on from that....
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 afree
on thecurrN
...just to be safe...