我遇到一个问题,打印循环列表是在无限循环中。在代码中,我创建了一个函数,它接收一个值n,即将插入列表中的元素数量和一个向量v。我循环遍历向量的每个元素,并根据n的大小将其添加到列表中。我认为我对代码块没有问题,因为错误是在打印过程中发生的,只有当它到达最后一个节点时
#include <stdio.h>
#include <stdlib.h>
struct circular_list {
int info;
struct circular_list *prox;
};
typedef struct circular_list CircularList;
CircularList* startList(CircularList *L){
return NULL;
}
void printList(CircularList *L){
CircularList *p=L;
if (p==NULL)
printf("nList is empty");
else{
do{
if (p->prox==L)
printf("%d", p->info);
else
printf("%d -> ", p->info);
p = p->prox;
}while(p!=L);
}
printf("n");
}
CircularList *build(int n, int *v)
{
CircularList *head = NULL;
for (int i = 0; i < n; i++)
{
CircularList *auxList = (CircularList*)malloc(sizeof(CircularList));
auxList->info = v[i];
if (head == NULL) {
auxList->prox = auxList;
} else {
auxList->prox = head;
}
head = auxList;
}
return head;
}
int main() {
CircularList* list;
int vector[5] = {13, 38, 21, 71, 21};
list = startList(list);
list = build(5, vector);
printList(list);
return 0;
}
有人能帮我吗?
此程序的输出开始为:
21 -> 71 -> 21 -> 38 -> 13 -> 13 -> 13 -> 13 -> 13 -> 13
从中我们可以看出,该列表的构建不正确。创建的第一个节点指向自身,函数不会返回预期的头节点。
事实上,列表是反向链接的,如果您更改向量的值,则更容易看到:
int vector[5] = {13, 38, 21, 71, 51};
51 -> 71 -> 21 -> 38 -> 13 -> 13 -> 13 -> 13 -> 13 -> 13
这是一个工作函数,我们在其中隔离头节点。
CircularList *build(int n, int *v)
{
CircularList *head = NULL;
CircularList *current = NULL;
for (int i = 0; i < n; i++) {
CircularList *auxList = malloc(sizeof *auxList);
auxList->info = v[i];
if (head == NULL) {
head = auxList;
} else {
current->prox = auxList;
}
current = auxList;
}
current->prox = head;
return head;
}
(已编辑(
我这样修改了main()
以进行调试。问题出在build()
代码上;数组中的第一个项是您到达的最后一个列表节点,它指向自己。
int main() {
CircularList* list;
int vector[5] = {13, 38, 21, 71, 21};
list = startList(list);
list = build(5, vector);
// printList(list);
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
printf("list node info: %d n", list->info);
printf("list node prox: %p n", list->prox);
list = list->prox;
return 0;
}
输出:
list node info: 21
list node prox: 0x7f8ae8405c50
list node info: 71
list node prox: 0x7f8ae8405c40
list node info: 21
list node prox: 0x7f8ae8405c30
list node info: 38
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
今天过得很慢,所以这里要重写您的代码。不要忘记,您必须使用free()
堆存储来防止内存泄漏。
请注意结构的重命名:节点就是节点。正是代码使其成为循环LL,而不是线性LL。一个节点就是一个节点。。。节点(通常(不是列表。。。
#include <stdio.h>
#include <stdlib.h>
typedef struct node { // combine things. Don't write more lines of code.
int info;
struct node *prox;
} node_t; // short & sweet name
node_t *printit( node_t *L ) {
// think about re-using as much code as you can
char *use = "nList is empty"; // set up defaults in case they are used.
if( L ) {
node_t *p = L;
use = ""; // default
do {
printf( "%s%d", use, p->info );
use = " -> "; // replaced
} while( (p = p->prox) != L ); // combine things
use = ""; // to output only a LF
}
puts( use );
return L; // magic can happen. see 'main()'
}
node_t *freeit( node_t *p ) { // Missing from your code
while( p && p != p->prox ) {
node_t *pDel = p->prox;
p->prox = p->prox->prox;
free( pDel );
}
free( p );
return NULL;
}
node_t *buildit( int n, int *v ) {
node_t *head = NULL, *tail = NULL;
for( int i = 0; i < n; i++ ) {
node_t *p = malloc( sizeof *p );
/* omitting test for NULL */ // be explicit
p->info = v[i];
// combine what you can to avoid too much code
// use the power of C syntax
if( head == NULL )
head = tail = p->prox = p;
else
(tail = tail->prox = p)->prox = head;
}
return head;
}
int main() {
// use short, meaningful names in trivial functions
int v[5] = { 13, 38, 21, 71, 21 };
node_t *l = buildit( sizeof v/sizeof v[0], v );
printit( l );
l = freeit( l ); // don't forget about this!
// setting 'l' to NULL ensures it is NULL if accidentally used again
/* more code ?? */
// and a bit of magic...
freeit( printit( buildit( sizeof v/sizeof v[0], v ) ) );
return 0;
}
13 -> 38 -> 21 -> 71 -> 21
13 -> 38 -> 21 -> 71 -> 21