我创建了一个链表,却想不出如何反转它。我知道算法,但我认为我在创建列表时犯了一个错误。反向功能有什么变化才能起作用。 以下是代码:
typedef struct Node{
int data;
struct Node* next;
} node;
node* head;
int count;
void insertAtBegin(int value){
if(head==NULL){
head = (node*)malloc(sizeof(node));
head->data = 0;
head->next = NULL;
}
node* newNode = (node*)malloc(sizeof(node));
newNode->data = value;
newNode->next = head->next;
head->next = newNode;
count++;
}
void display(){
node* temp = (node*)malloc(sizeof(node));
temp = head;
while(temp->next!=NULL){
printf("%d\t",temp->next->data);
temp = temp->next;
}
printf("\n");
}
void reverse(){
node *p, *q, *r;
p = q = r = head;
p = p->next->next;
q = q->next;
r->next = NULL;
q->next = r;
while (p != NULL){
r = q;
q = p;
p = p->next;
q->next = r;
}
head = q;
}
void main(){
insertAtBegin(5);
insertAtBegin(6);
display();
reverse();
display();
printf("\nSize of linked list is %d",count);
}
答案 0 :(得分:1)
假设您有以下列表:
head = n0
n0 -> ... -> A -> B -> C -> D -> E -> ... -> nN -> NULL
你要反向:
head = nN
nN -> ... -> E -> D -> C -> B -> A -> ... -> n0 -> NULL
现在,让我们考虑列表开头已经颠倒并且您正在处理节点C
的情况。你当时的名单是:
head = B
B -> A -> ... -> n0-> NULL
tmpHead = C
C -> D -> E ... -> nN -> NULL
其中tmpHead
是一个临时变量,可让您不会丢失对C
的引用(因为B.next
现在指向A
)您希望:
B
与C
联系起来B
C
C
,反向列表的新主管D
保留在临时变量tmpHead
中,以便您仍然可以访问它然后反转成为:
node * tmp = tmpHead.next; // 3. part 1
tmpHead.next = head; // 1.
head = tmpHead; // 2.
tmpHead = tmp; // 3. part 2
停止条件非常明显:当您到达列表末尾时必须停止,因此,当tmpHead
为NULL
时。至于初始化,head
指向反转部分,tmpHead
指向非反转部分。因此tmpHead
必须设置为head
,head
设置为NULL
。
最后,您将获得以下函数,该函数将指向列表第一个节点的指针作为输入参数
void reverse(node ** head)
{
node * tmpHead = (* head);
(* head) = NULL;
while(tmpHead)
{
node * tmp = tmpHead->next;
tmpHead->next = (* head);
(* head) = tmpHead;
tmpHead = tmp;
}
}
请注意,在列表开头插入新节点的方式存在“问题”:您始终保持“幻像”节点,数据设置为0
并且您调用head
}。因此,我定义的列表的第一个真实节点是head->next
。这意味着你必须像这样调用reverse
函数:reverse(& (head->next))
或略微修改函数。
另外,请注意,您不应该转换malloc的结果。 Do I cast the result of malloc?