C 交换单链表中的节点
我正在尝试交换两个节点。例如,如果节点是C 交换单链表中的节点,c,pointers,swap,singly-linked-list,C,Pointers,Swap,Singly Linked List,我正在尝试交换两个节点。例如,如果节点是a和b我正在传递指针 (a-1)->next和(b-1)->next基本上是节点a和b void swap(struct stack **a,struct stack **b) { struct stack *temp1 = *a, *temp2 = *b, *temp3 = *b; *a = *b; (*b)->next = (temp1)->next; temp2 = temp1; (t
a
和b
我正在传递指针(a-1)->next
和(b-1)->next
基本上是节点a
和b
void swap(struct stack **a,struct stack **b)
{
struct stack *temp1 = *a, *temp2 = *b, *temp3 = *b;
*a = *b;
(*b)->next = (temp1)->next;
temp2 = temp1;
(temp2)->next = temp3->next;
}
node[9] points to node[2]
node[6] points to node[5]
我做错了什么?当我在调用函数后试图打印节点时,它是一个无限循环。请帮助。为什么是无限循环?
node[9] points to node[2]
node[6] points to node[5]
无限循环是因为调用swap()
函数后列表中出现了自循环。在swap()
(*b)->next = (temp1)->next;
node[9] points to node[2]
node[6] points to node[5]
为什么?:因为在swap()
函数temp1
中的赋值语句之后,下一个开始指向b
节点。和节点[b]
的下一个循环点。而自循环是无限循环的原因,在代码中遍历链表的某个地方
node[9] points to node[2]
node[6] points to node[5]
下面我画了一幅图,展示了swap()
如何一步一步地工作。这可能有助于您理解错误:
node[9] points to node[2]
node[6] points to node[5]
您没有提到,但我假设链表在a
和b
之间有以下关系:(阅读红色注释)
node[9] points to node[2]
node[6] points to node[5]
(步骤1):
+----+----+----+ +---+----+----+
| one |----->| two |
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| *a | *b
| |
temp1 temp2, temp3 "after assignment to temp variables"
(step-2): ^
|
*a = *b | *a "<--- next step"
node[9] points to node[2]
node[6] points to node[5]
+---+ +---+ +---+ +---+ +---+
| 0 |--->| 6 |--->| 2 |--->| 9 |--->| 5 |---
+---+ +---+ +---+ +---+ +---+ |
^ ^ ^ null
| | |
| (p) (q)
(head)
以下是我这两行的示意图:
temp2 = temp1;
+----+----+----+ +---+----+----+ <---|
| one | | two |-----| "<--- Self loop"
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp2 = temp1; temp3
node[9] points to node[2]
node[6] points to node[5]
所以循环仍然存在于two
节点,所以循环是无限的
node[9] points to node[2]
node[6] points to node[5]
如何交换单链表中的两个节点?
一种方法是交换节点的数据,而不是交换节点在链表中的位置(正如我对您的问题的评论)。但是您想交换节点在列表中的位置。
好吧,这太好了!如果节点数据大小更大,那么最好交换节点的位置,而不是交换节点的数据(交换数据将是错误的选择)
node[9] points to node[2]
node[6] points to node[5]
因为您有单链表,所以要交换列表中的任意两个节点,您也需要有以前的节点地址。(这是你在交换逻辑中不考虑的点)
node[9] points to node[2]
node[6] points to node[5]
为什么需要前面的指针?:
假设在一些成功的插入(推送)操作之后,您的列表如下所示:
0 <--------TOP - "head"
9 <--p
2
6 <--q
5
node[9] points to node[2]
node[6] points to node[5]
正如我所说,为了交换,我们需要前面的指针。您需要考虑以下内容
(理论上,我是为特定的节点(p)
和(q)
编写的,只是为了让解释更简单。但我的实现是通用的):
node[9] points to node[2]
node[6] points to node[5]
在前面的指针列表中:
node[0] points to node[9] that is (q), and
node[2] points to node[6] that is (p)
node[9] points to node[2]
node[6] points to node[5]
及
node[9] points to node[2]
node[6] points to node[5]
注意:如果要交换两个节点,如节点[9]
和节点[6]
,则应使用这两个节点之前的节点指针。
例如:两个交换节点[9]
和[6]
,您还需要更改上图中节点[0]
的下一个指针和节点[2]
的下一个指针
node[9] points to node[2]
node[6] points to node[5]
交换这两个节点后,列表将如何显示?
+----+----+----+ +---+----+----+
| one |----->| two |
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| *a | *b
| |
temp1 temp2, temp3 "after assignment to temp variables"
(step-2): ^
|
*a = *b | *a "<--- next step"
node[9] points to node[2]
node[6] points to node[5]
+---+ +---+ +---+ +---+ +---+
| 0 |--->| 6 |--->| 2 |--->| 9 |--->| 5 |---
+---+ +---+ +---+ +---+ +---+ |
^ ^ ^ null
| | |
| (p) (q)
(head)
以前的节点[o]
和[2]
中现在是什么?
交换后,在列表中列出以前的指针
node[9] points to node[2]
node[6] points to node[5]
node[0] points to node[6] that is (q), and
node[2] points to node[9] that is (p)
及
node[9] points to node[2]
node[6] points to node[5]
所以如果你想交换两个节点;前面的节点也会产生影响,因为列表是单链接列表,所以您也需要前面的指针
node[9] points to node[2]
node[6] points to node[5]
如何查找以前的节点指针?
node[9] points to node[2]
node[6] points to node[5]
假设要交换任意两个节点节点[p]
和节点[q]
,则可以使用头指针
查找上一个节点
node[9] points to node[2]
node[6] points to node[5]
因此交换函数语法(在我的实现中)如下所示:
node[9] points to node[2]
node[6] points to node[5]
void swap(struct stack **head, // head node
struct stack **a, // first candidate node to swap
struct stack **b); // first candidate node to swap
您将调用如下函数:
node[9] points to node[2]
node[6] points to node[5]
swap(&head, &p, &q);
定义:(要理解代码,请阅读我在几乎每行添加的注释)
node[9] points to node[2]
node[6] points to node[5]
在swap()代码>。此函数返回列表中上一个节点的地址。在函数get_prevend(,)中代码>,第一个参数是列表头,第二个参数是要查找的节点
node[9] points to node[2]
node[6] points to node[5]
// find previous node function()
struct stack* get_prevnd(
struct stack* head,
struct stack* a
){
if(head == a){
// node[a] is first node
return NULL;
}
struct stack* temp = head; // temp is current node
struct stack* pre_a = NULL;
while(temp && temp!=a){ //search while not reach to end or the node
pre_a = temp; // find previous node
temp = temp->next;
}
if(temp!=a){// node[a] not present in list
fprintf(stderr, "\n error: node not found!\n");
exit(EXIT_FAILURE); // bad technique to exit()
}
return pre_a;
}
幸运的是,代码正在工作:)。下面是这个代码在线测试的链接。我测试了各种输入
node[9] points to node[2]
node[6] points to node[5]
代码板:请检查输出
node[9] points to node[2]
node[6] points to node[5]
对不起,英语不好
node[9] points to node[2]
node[6] points to node[5]
SwapanyTwoNodeData(int,int)
此函数将两个整数作为参数,并交换它们
node[9] points to node[2]
node[6] points to node[5]
节点数据
node[9] points to node[2]
node[6] points to node[5]
1->2->6->3->4->5
swpanytwonodedata(2,4)代码>
node[9] points to node[2]
node[6] points to node[5]
1->3->6->2->4->5
100%工作功能。享受
node[9] points to node[2]
node[6] points to node[5]
void Swap_Any_Two_Locations_data(int x,int x1){
if(head!=NULL){
int count=1,count1=1;
Node *temp,*temp1;
temp=head;
temp1=head;
while(temp->next!=NULL && count!=x ){
temp=temp->next;
count++;
}
while(temp1->next!=NULL && count1!=x1){
temp1=temp1->next;
count1++;
}
if(count==x && count1==x1){
int z=0;
z=temp->info;
temp->info=temp1->info;
temp1->info=z;
cout<<"Data Swapped"<<endl;
}
}
}
无效交换任意两个位置的数据(int x,int x1){
如果(head!=NULL){
int count=1,count1=1;
节点*temp,*temp1;
温度=水头;
temp1=头部;
while(临时->下一步!=NULL&&count!=x){
温度=温度->下一步;
计数++;
}
while(temp1->next!=NULL&&count1!=x1){
temp1=temp1->next;
count1++;
}
if(count==x&&count1==x1){
int z=0;
z=温度->信息;
temp->info=temp1->info;
temp1->info=z;
cout我希望剪切粘贴代码,但没有找到。如果还有人感兴趣,这就是答案。我对所有3个案例进行了暴力分析
node[9] points to node[2]
node[6] points to node[5]
// swaps nodes at locations *sp and *tp
struct stack *s = *sp; // store locations to prevent overwritten bugs
struct stack *t = *tp;
if(&t->next == sp) { // order u (tp)-> t (sp)-> s -> ...
t->next = s->next;
s->next = t;
*tp = s;
} else if(&s->next == tp) { // order u (sp)-> s (tp)-> t -> ...
s->next = t->next;
t->next = s;
*sp = t;
} else { // disconnected u (sp)->s -> ..., v (tp)->t -> ...
struct stack *next = s->next;
s->next = t->next;
t->next = next;
*sp = t;
*tp = s;
}
// If you track the end of your list, it be the one pointing to NULL.
if(s->next == NULL) {
end = &s->next;
} else if(t->next == NULL) {
end = &t->next;
}
注意:此代码在sp==tp时有效,但假设您没有&s->next==tp&&t->next==sp(从循环开始)的病理情况虽然你只能用WASP数据,但是如果你想要的是节点,那么C++就不多了,只有C。你应该使用C++,并且用它代替现有的。我想简单地交换数据会更容易:<代码> DATAYTYPE TYMP=(*A)->数据;(*A)->数据=(*B)->数据;(*B)->data=temp;
@伙计们,我的代码有什么问题?:)@us2012-不使用它的原因是因为你被要求去理解它。这可能是一个学校项目,教授在OP自己完成之前不允许OP这么做。我理解反对这种教学方式的论点,因为我在这里读了一段时间这并没有改变我们中的一些人,包括我在内,都受到它的影响。没有规则规定你必须使用STL
它只是sma
node[9] points to node[2]
node[6] points to node[5]