读书人

C链表里的倒序排列解决方法

发布时间: 2012-02-05 12:07:15 作者: rapoo

C链表里的倒序排列
问结点数据域依次为 a1,a2.........,an的一个单链表所有结点逆置,即第一个结点数据域变为 an
最后一个结点数据域变为 a1?
这个应该怎么做呢?

[解决办法]
#include <stdio.h>
#include <stdlib.h>
//单链表
typedef struct NODE
{
int value;
struct NODE *next;

}Node ;

Node * create()
{
Node * head , *end, *p;
int data;
char str;


head = end = NULL;
puts( "input data:\n ");
while(scanf( "%d ",&data)==1)
{
p = (Node *)malloc(sizeof(Node));

p-> value = data;
p-> next = NULL;

if(head == NULL)
{
head = end = p;
p-> next =NULL;
}
else
{
end-> next = p;
end = p;
p-> next = NULL;
}




}
scanf( "%c ",&str);
return head;
}


Node * ReverseList(Node *head)
{
Node *p1 =NULL, *p2 = NULL, *p3 = NULL;
p1 = head;

if( (p1 == NULL) || (p1-> next == NULL))
{
return p1;
}

p2 = p1-> next;
p3 = p2-> next;
while(p3 != NULL)
{
//printf( ".....%d..%d..%d..\n ",p1-> value,p2-> value,p3-> value);
p2-> next = p1;
p1= p2;
p2 = p3;
p3 = p3-> next;

}



head-> next =NULL;
p2-> next = p1;
head = p2;

return head;
}

void free_list(Node *head)
{
Node *p = NULL;

while(head != NULL)
{
p=head;
head=head-> next;
free(p);
}


}

Node * Merge(Node *head1 , Node *head2)
{
Node *temp = NULL, *list = NULL;
Node *Head = NULL;

if((head1 == NULL) && (head2 == NULL))
{
puts( "Frisr list and Second list is NULL.\n ");
return NULL;
}
if(head1 == NULL)
return head2;

if(head2 == NULL)
return head1;


if(head1-> value <= head2-> value)
Head = list = head1;
else
Head = list = head2;

while( (head1 != NULL) && (head2 != NULL))
{

if(head1-> value <= head2-> value)
{
temp = head1;
head1 = head1-> next;
}
else
{
temp = head2;
head2 = head2-> next;
}

list-> next= temp;
list = temp;
list-> next = NULL;
}

if(head1 != NULL)
{
list-> next=head1;
}
if(head2 != NULL)
{
list-> next = head2;
}


return Head;


}


int main()
{
Node *head1,*end1;
Node *head2,*end2;


head1 =end1 = create();
head2 = end2 = create();

puts( "\nFirst list: ");
//---------------------
if(end1 == NULL )
puts( "first list is NULL.\n ");
else{
while(end1 != NULL)
{
printf( "%-4d ",end1-> value);
end1=end1-> next;
}

}

puts( "\nsecond list: ");
if(end2 == NULL )
puts( "second list is NULL.\n ");
else
{
while(end2 != NULL)
{
printf( "%-4d ",end2-> value);
end2=end2-> next;


}
}
//-----------------------------
/*puts( "\nNode * Reverse List1 :\n ");
head1=end1= ReverseList(head1);
if(end1 == NULL )
puts( "first list is NULL.\n ");
else{
while(end1 != NULL)
{
printf( "%-4d ",end1-> value);
end1=end1-> next;
}

}
*/


//-----------------------------
puts( "\nAfter Node * Merge(Node *head1 , Node *head2).\n ");
head1 = end1=Merge(head1 ,head2);

while(end1 != NULL)
{
printf( "%-4d ",end1-> value);
end1=end1-> next;
}




free_list(head1);//自己要释放所有分配结点空间
return 0;
}



[解决办法]
翻转单链表
struct link *reverse(struct link *head)
{
struct link *p, *q;

p = head-> next;
head-> next = NULL;
while ( p != NULL)
{
q = p;
p = p-> next;
q-> next = head-> next;
head-> next = q;
}
return head;
}


[解决办法]
如果节点少,冒泡法还可以.

为了利用其他排序方法像qsort
你可以创建一个数组(动态数组)
数组单元中保存的是每个节点的地址
然后对该数组排序
最后,按照数组中地址的顺序重新连接链表并释放掉数组所占空间.

读书人网 >C++

热点推荐