我正在尝试创建链接列表并按冒险排序对其进行排序。我成功地创建了链接列表,但是当我尝试冒泡它时,发生了一些事故,我不知道问题。有什么问题?
#include <stdio.h>
#include <stdlib.h>
//the struct of LinkedList
typedef struct Node
{
int data;
struct Node * pNext;
}NODE,*PNODE;
PNODE createList();//Creat one LinkedList
int lengthList(PNODE pHead);//get the length of LinkedList
void sortList(PNODE);//bubble sort
int main()
{
int length;
PNODE pHead=NULL;
pHead=createList();
sortList(pHead);
return 0;
}
//Create LinkedList
PNODE createList()
{
int i,n;
int val;
PNODE pHead=(PNODE)malloc(sizeof(NODE));
if(pHead==NULL)
{
printf("failed to create!\n");
exit(-1);
}
pHead->pNext=NULL;
PNODE pTail=pHead;
printf("please input the length of the LinkedList:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("number %d is:\n",i+1);
scanf("%d",&val);
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(pNew==NULL)
{
printf("failed to create\n");
exit(-1);
}
pNew->data=val;
pTail->pNext=pNew;
pNew->pNext=NULL;
pTail=pNew;
}
return pHead;
}
//get the length of LinkedList
int lengthList(PNODE pHead)
{
int i=0;
PNODE p=pHead->pNext;
while(p!=NULL)
{
i++;
p=p->pNext;
}
return i;
}
//bubble sort
void sortList(PNODE pHead)
{
int i,j,t,len;
PNODE p,q;
len=lengthList(pHead);
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
if( p->data > q->data)
{
t=p->data;
p->data=q->data;
q->data=t;
}
p=q;//here may be the error
}
}
return;
}
答案 0 :(得分:0)
您正在sortList
中的列表末尾运行p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
....
p=q;//here may be the error
}
}
错误1)您的列表只有len
长,但您尝试将p
提升到p->pNext
远远超过len
次。
错误2)pHead不需要是一个完整的NODE - 它只是一个PNODE指针。你永远不会使用它的数据字段。你应该让pHead指向列表中的第一个节点,然后在pHead而不是pHead-> pNext开始你的迭代。
错误3)你永远不会清理内存分配。
答案 1 :(得分:0)
由于@Airsource指出了这些错误,请记住,大多数错误都是由于程序设计选择不当引起的。尝试像下面这样做&amp;你会遇到更少的错误
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _Node{
int data;
struct _Node* next;
}Node;
typedef struct {
Node* headPtr;
Node* tailPtr;
unsigned size;
}List;
static void create_node(List* list, int element) {
if (list->headPtr == NULL) {
// List is empty
list->headPtr = (Node* )malloc(sizeof(Node));
list->headPtr->data = element;
list->headPtr->next = 0;
list->tailPtr = list->headPtr;
list->size++;
}else{
// List was already populated
Node* temp = (Node* )malloc(sizeof(Node));
temp->data = element;
temp->next = 0;
list->tailPtr->next = temp;
list->tailPtr = temp;
list->size++;
}
}
void create_list(List* list, int length){
int ele;
int i;
list->headPtr = list->tailPtr = 0;
list->size = 0;
for (i = 0; i < length; i++) {
scanf("%d", &ele);
create_node(list, ele);
}
}
void print_list(List* list){
Node* loop = list->headPtr;
while(loop){
printf("%d ", loop->data);
loop = loop->next;
}
printf("\n");
}
int main(){
List* list;
int n;
printf("Enter the length of the list: ");
scanf("%d", &n);
create_list(list, n);
print_list(list);
bubble_sort(list);
print_list(list);
if (cleanup(list))
printf("Memory rescued!!\n");
else
printf("OOPS!! Error\n");
return 0;
}
此外,您可以随时list->size
获取尺寸。不需要单独的功能。
最后要使用冒泡排序对其进行排序,您可以执行以下操作
void bubble_sort(List* list) {
int i, j;
Node* first, *second;
int temp;
first = list->headPtr;
second = list->headPtr->next;
for (i = 0; i < list->size - 1; i++) {
for (j = 0; j < list->size - i - 1; j++) {
if (first->data > second->data){
temp = first->data;
first->data = second->data;
second->data = temp;
}
first = second;
second = second->next;
}
first = list->headPtr;
second = list->headPtr->next;
}
}
并进行清理,你可以这样做
bool cleanup(List* list) {
Node* curr = list->headPtr;
Node* nxt = list->headPtr->next;
while(nxt){
free(curr);
curr = nxt;
nxt = curr->next;
}
list->headPtr = list->tailPtr = 0;
list->size = 0;
return !nxt ? true: false;
}
答案 2 :(得分:0)
你的程序中有几个错误。我将逐一解决这些问题:
第28行PNODE pHead=(PNODE)malloc(sizeof(NODE));
在这里,您要在检查n> 0之前分配内存并创建节点。
第36行printf("please input the length of the LinkedList:");
到目前为止,您已经创建了一个节点head
节点,其中包含 no 值(因此包含垃圾)
实际上,您的createList()
会创建一个包含n+1
个节点而不是n
的链接列表,而head->value
包含垃圾。
解决方案:
printf("please input the length of the LinkedList:");
scanf("%d", &n);
for(i=0; i<n; i++)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(pNew == NULL)
{
printf("failed to create!\n");
exit(-1);
}
scanf("%d", &val);
pNew->data = val;
pNew->pNext = NULL;
if (!i)
pHead = pNew;
else
pTail->pNext = pNew;
pTail = pNew;
}
return pHead;
PNODE p=pHead->pNext;
head
)。难怪您将length
作为n
获得,因为您在n+1
createList()
的链接列表
醇>
想象一下如果n = 0
和pHead = NULL
会是什么?
然后这一行将导致SegFault
。
解决方案:
将PNODE p=pHead->pNext;
更改为PNODE p = pHead;
第73行p=pHead->pNext;
在这里,您将开始排序,排除第一个节点head
节点
此外,这应该在内部for
内部以及内部for
之外,以便为每次传递将p
重置为第一个节点。
第76行for(j=0;j<len-i;j++)
这里的j必须小于len - 1 - i
,因为在第1行(i = 0
)中,在最坏的情况下j对于len-1
将等于j < len-i
,其中p
将指向链接列表的最后一个节点,q
将为q = p -> pNext
为NULL。这会使q->data
导致SegFault
。
总而言之,您的排序例程在第一个Pass中生成SegFault
,即使它没有(通过正确调整内部for
中的循环终止表达式)外部{除了增加时间复杂度之外,{1}}循环对排序没有贡献。
解决方案:
for
一个问题:
你如何检查元素是否已经分类?
for(i = 0; i < len - 1; i++)
{
p = pHead;
for(j = 0; j < len - 1 - i; j++)
{
q = p -> pNext;
if(p->data > q->data)
{
t = p -> data;
p -> data = q -> data;
q -> data = t;
}
p = q;
}
}
例程有助于发现上述错误。
&#34;在处理输入之前,请务必先验证是否正确存储了输入!&#34;