C 循环链表在显示时崩溃
我想做一个循环链表。当我试图在创建列表后显示它时,程序不断崩溃。这是我的密码:C 循环链表在显示时崩溃,c,data-structures,linked-list,circular-list,C,Data Structures,Linked List,Circular List,我想做一个循环链表。当我试图在创建列表后显示它时,程序不断崩溃。这是我的密码: #include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node * next; } node; node * createList(int); void display(node * head); int main() { struct node * head;
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node * next;
} node;
node * createList(int);
void display(node * head);
int main() {
struct node * head;
head = createList(5);
display(head);
}
node * createList(int n) {
int i = 0,data = 0;
struct node * head = NULL;
struct node * temp = NULL;
struct node * p = NULL;
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = head;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
void display(node * head) {
struct node * temp = head->next;
while (temp != head) {
printf("%d-> \t",temp->data);
temp = temp->next;
}
printf("\n");
}
#包括
#包括
类型定义结构节点{
int数据;
结构节点*下一步;
}节点;
节点*createList(int);
无效显示(节点*头部);
int main(){
结构节点*头部;
head=createList(5);
显示器(头部);
}
节点*createList(int n){
int i=0,data=0;
结构节点*head=NULL;
结构节点*temp=NULL;
结构节点*p=NULL;
对于(i=0;i数据=数据++;
温度->下一步=头部;
if(head==NULL){
压头=温度;
}否则{
p=水头;
while(p->next!=NULL){
p=p->next;
}
p->next=温度;
}
}
回流头;
}
无效显示(节点*头部){
结构节点*temp=head->next;
while(温度!=头部){
printf(“%d->\t”,临时->数据);
温度=温度->下一步;
}
printf(“\n”);
}
我做错了什么
temp->next=head中将每个temp
的next
设置为head
但是做得太早了(第一个只是NULL
)。然后您在中对p->next
和NULL
进行了测试,而(p->next!=NULL){
但是您应该针对head
进行测试。或者,您可以继续针对NULL
进行测试,但是您需要将temp->next
初始化为NULL
,并仅在for循环之后将head
分配给temp->next
1中的第一个选项的固定代码。
:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != head) {
p = p->next;
}
p->next = temp;
}
temp->next = head;
}
但实际上,没有必要在每一个创造物上都从头开始“走”。你只需保留上一个创造物并将其链接到下一个创造物:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = p = temp;
} else {
p = p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
问题出现在您初始化的第一个节点上:
struct node *head = NULL;
...
for (i = 0; i < n; i++) {
...
temp->next = head;
什么是head->next
再次??(哦,NULL
)解除对NULL
指针的引用(BOOM Segfault!)
正确执行循环列表。插入第一个节点集时:
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} ...
因此,在插入其余节点时,您只需:
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
现在,以相同的方式处理display()
函数,例如:
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
如果进行了更改,则可以使用以下工具测试列表:
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
示例使用/输出
$。/bin/lls\u循环\u修复
0-> 1-> 2-> 3-> 4->
从中间列表迭代
2-> 3-> 4-> 0-> 1->
最后,在struct node*head=NULL;
中,将类型node
乘以head
;将其写为struct node*head=NULL;
(对于所有函数声明也是如此)可读性更强
当您要从列表中删除注释时,必须为head
和tail
(最后一个节点)创建一个特例。从这个意义上说,由于没有prev
节点指针来跟踪前一个节点,单链接列表比双链接列表要花费更多的精力
仔细检查一下,如果有问题请告诉我
一个完整的例子是:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createList (int);
void display (node *head);
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
node *createList (int n)
{
int i = 0,data = 0;
struct node *head = NULL;
struct node *temp = NULL;
struct node *p = NULL;
for (i = 0; i < n; i++) {
if (!(temp = malloc (sizeof *temp))) {
perror ("malloc-temp");
return NULL;
}
temp->data = data++;
temp->next = head; /* head is NULL on 1st node insertion */
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
}
return head;
}
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
#包括
#包括
类型定义结构节点{
int数据;
结构节点*下一步;
}节点;
节点*createList(int);
无效显示(节点*头部);
内部主(空){
结构节点*head,*tmp;
head=createList(5);
显示器(头部);
puts(“\n从中间列表中删除”);
tmp=头部;
tmp=tmp->next;
tmp=tmp->next;
显示器(tmp);
}
节点*createList(int n)
{
int i=0,data=0;
结构节点*head=NULL;
结构节点*temp=NULL;
结构节点*p=NULL;
对于(i=0;i数据=数据++;
temp->next=head;/*第一次插入节点时head为空*/
if(head==NULL){
压头=温度;
head->next=temp;/*必须将head->next设置为temp*/
}否则{
p=水头;
而(p->next!=head){/*迭代到最后一个节点*/
p=p->next;
}
p->next=temp;/*现在设置p->next=temp*/
}
}
回流头;
}
无效显示(节点*头部)
{
如果(!head){/*验证列表不为空*/
puts(“(列表为空)”);
返回;
}
结构节点*温度=头部;
是否在display()中修复了{/*相同的循环问题*/
printf(“%d->\t”,临时->数据);
温度=温度->下一步;
}while(temp!=头部);
putchar('\n');
}
提示:解释这行代码:temp->next=head;
它的目标是什么?(它导致while(p->next!=NULL){
永远循环。)循环列表中不会有while(p->next!=NULL)
——最后一个节点->下一个指针指向head节点(因此是循环列表)谢谢你的回复,我已经尝试了你的代码,但它仍然在崩溃:/@VenoM我还将temp->next
初始化为NULL
,现在就试试吧,添加temp->next=NULL成功了,谢谢!
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createList (int);
void display (node *head);
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
node *createList (int n)
{
int i = 0,data = 0;
struct node *head = NULL;
struct node *temp = NULL;
struct node *p = NULL;
for (i = 0; i < n; i++) {
if (!(temp = malloc (sizeof *temp))) {
perror ("malloc-temp");
return NULL;
}
temp->data = data++;
temp->next = head; /* head is NULL on 1st node insertion */
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
}
return head;
}
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}