我一直在尝试编写一段代码,将两个整数有序列表合并为一个整数有序列表。
函数ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )应该接收指向两个列表中每个列表的第一个节点的指针。
除了合并功能之外,其他所有功能似乎都可以正常工作。
问题似乎是它去掉了较短列表中的最后一个元素。
//12.7 merge two ordered lists into one ordered list
#include <stdio.h>
#include <stdlib.h>
struct listNode
{
int data;
struct listNode *nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;
void insert( ListNodePtr *sPtr, int value );
ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr );
int isEmpty( ListNodePtr currentPtr );
void printList( ListNodePtr currentPtr );
void instructions(void);
int main(void)
{
ListNodePtr startPtr1 = NULL;
ListNodePtr startPtr2 = NULL;
unsigned int choice;
int item;
instructions();
printf("\n?");
scanf("%u",&choice);
while (choice != 4)
{
switch (choice)
{
case 1:
printf("Enter a character into list 1:\n");
scanf("\n%d",&item);
insert( &startPtr1, item );
printList( startPtr1 );
break;
case 2:
printf("Enter a character into list 2:\n");
scanf("\n%d",&item);
insert( &startPtr2, item );
printList( startPtr2 );
break;
case 3:
if (isEmpty(startPtr1) && isEmpty(startPtr2))
{
puts("Both lists are empty.");
}
else if (isEmpty(startPtr1))
{
puts("List 1 is empty.");
}
else if (isEmpty(startPtr2))
{
puts("List 2 is empty.");
}
else
{
printList( startPtr1 );
printList( startPtr2 );
puts("Merged list:");
printList( merge( startPtr1, startPtr2 ) );
}
break;
default:
printf("Invalid choice.\n");
instructions();
break;
}
printf("\n?");
scanf("%u",&choice);
}
puts("End of run.");
}
void instructions(void)
{
printf("Enter your choice:\n"
" 1 to insert an number into list 1.\n"
" 2 to insert an number into list 2.\n"
" 3 to merge and order list 1 and list 2.\n"
" 4 to end.");
}
void insert( ListNodePtr *sPtr, int value )
{
ListNodePtr newPtr;
ListNodePtr previousPtr;
ListNodePtr currentPtr;
newPtr = (ListNodePtr)malloc(sizeof(ListNode));
if (newPtr != NULL)
{
newPtr->data = value;
newPtr->nextPtr = NULL;
previousPtr = NULL;
currentPtr = *sPtr;
while (currentPtr != NULL && value > currentPtr->data)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (previousPtr == NULL)
{
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}
else
{
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
{
printf( "%d not inserted. No memory available.", value );
}
}
ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )
{
ListNode merge;
ListNodePtr mergePtr = &merge;
//PROBLEM: merge.nextPtr will be missing second to last element
//in final merged list
while ( xPtr->nextPtr != NULL && yPtr->nextPtr != NULL)
{
if ( xPtr->data < yPtr->data)
{
mergePtr->nextPtr = xPtr;
xPtr = xPtr->nextPtr;
mergePtr = mergePtr->nextPtr;
}//end if
if ( yPtr->data < xPtr->data)
{
mergePtr->nextPtr = yPtr;
yPtr = yPtr->nextPtr;
mergePtr = mergePtr->nextPtr;
}//end if
}//end of while
if ( xPtr->nextPtr == NULL )
{
mergePtr->nextPtr = yPtr;
}
if ( yPtr->nextPtr == NULL )
{
mergePtr->nextPtr = xPtr;
}
return merge.nextPtr;
}//end of function merge
int isEmpty( ListNodePtr sPtr )
{
return sPtr == NULL;
}
void printList( ListNodePtr currentPtr )
{
if ( isEmpty(currentPtr) )
{
puts("List is empty");
}
else
{
while ( currentPtr != NULL )
{
printf("%d --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("NULL");
}
}有人能解决这个问题吗?我已经学习C编程语言一个半月了。
发布于 2013-07-25 06:47:11
我稍微修改了一下你的代码,它运行的很完美!
//12.7 merge two ordered lists into one ordered list
#include <stdio.h>
#include <stdlib.h>
struct listNode
{
! int data;
struct listNode *nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;
void insert( ListNodePtr *sPtr, int value );
ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr );
int isEmpty( ListNodePtr currentPtr );
void printList( ListNodePtr currentPtr );
void instructions(void);
int main(void)
{
ListNodePtr startPtr1 = NULL;
ListNodePtr startPtr2 = NULL;
unsigned int choice;
int item;
instructions();
printf("\n?");
scanf("%u",&choice);
while (choice != 4)
{
switch (choice)
{
case 1:
printf("Enter a character into list 1:\n");
scanf("\n%d",&item);
insert( &startPtr1, item );
printList( startPtr1 );
break;
case 2:
printf("Enter a character into list 2:\n");
scanf("\n%d",&item);
insert( &startPtr2, item );
printList( startPtr2 );
break;
case 3:
if (isEmpty(startPtr1) && isEmpty(startPtr2))
{
puts("Both lists are empty.");
}
else if (isEmpty(startPtr1))
{
puts("List 1 is empty.");
}
else if (isEmpty(startPtr2))
{
puts("List 2 is empty.");
}
else
{
printList( startPtr1 );
printList( startPtr2 );
puts("Merged list:");
printList( merge( startPtr1, startPtr2 ) );
}
break;
default:
printf("Invalid choice.\n");
instructions();
break;
}
printf("\n?");
scanf("%u",&choice);
}
puts("End of run.");
}
void instructions(void)
{
printf("Enter your choice:\n"
" 1 to insert an number into list 1.\n"
" 2 to insert an number into list 2.\n"
" 3 to merge and order list 1 and list 2.\n"
" 4 to end.");
}
void insert( ListNodePtr *sPtr, int value )
{
ListNodePtr newPtr;
ListNodePtr previousPtr;
ListNodePtr currentPtr;
newPtr = (ListNodePtr)malloc(sizeof(ListNode));
if (newPtr != NULL)
{
newPtr->data = value;
newPtr->nextPtr = NULL;
previousPtr = NULL;
currentPtr = *sPtr;
while (currentPtr != NULL && value > currentPtr->data)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (previousPtr == NULL)
{
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}
else
{
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
{
printf( "%d not inserted. No memory available.", value );
}
}
ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )
{
ListNode merge;
ListNodePtr begin, mergePtr = &merge; //here
begin = mergePtr; //here
//PROBLEM: merge.nextPtr will be missing second to last element
//in final merged list
while ( xPtr != NULL && yPtr != NULL) //here 2 now I deal with the last of short link!
{
if ( xPtr->data < yPtr->data)
{
mergePtr->nextPtr = xPtr;
xPtr = xPtr->nextPtr;
mergePtr = mergePtr->nextPtr;
}//end if
else// ( yPtr->data < xPtr->data) //here for yPtr->data == xPtr->data
{
mergePtr->nextPtr = yPtr;
yPtr = yPtr->nextPtr;
mergePtr = mergePtr->nextPtr;
}//end if
}//end of while
if ( xPtr != NULL ) //here 2
{
mergePtr->nextPtr = xPtr;
}
if ( yPtr != NULL ) //here 2
{
mergePtr->nextPtr = yPtr;
}
return begin->nextPtr; //here
}//end of function merge
int isEmpty( ListNodePtr sPtr )
{
return sPtr == NULL;
}
void printList( ListNodePtr currentPtr )
{
if ( isEmpty(currentPtr) )
{
puts("List is empty");
}
else
{
while ( currentPtr != NULL )
{
printf("%d --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("NULL");
}
}发布于 2013-07-25 04:38:42
由于您正在检查下一个值是否为null,因此当您命中最后一个值时,您将中断merge while循环。在这个while循环之外,您应该将另一个列表追加到另一个列表中。因此,如果List1用完了所有元素,而List2还有3个元素,那么不用遍历List2,只需生成(end of List1)->next =(您在List2中停下来的地方)。
另外,不要在merge函数中返回。你不需要这么做。因为yoru列表已经占用了空间,所以你只需要切换它们的指针所指向的位置。一旦完成了所有指针,只需像通常那样从函数返回一个访问列表1/列表2(除非您需要找出哪个列表包含第一个指针,所以只返回1或2)
此外,您也不会将merge设置为我不认为的值
发布于 2013-07-25 06:24:25
ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )
{
ListNode merge;
ListNodePtr mergePtr = &merge;
while ( xPtr != NULL && yPtr != NULL)
{
if ( xPtr->data < yPtr->data)
{
mergePtr->nextPtr = xPtr;
xPtr = xPtr->nextPtr;
mergePtr = mergePtr->nextPtr;
} else if ( yPtr->data < xPtr->data)//need else because 1 loop 2 ecxecute merge
{
mergePtr->nextPtr = yPtr;
yPtr = yPtr->nextPtr;
mergePtr = mergePtr->nextPtr;
}//end if
//nothing case of (yPtr->data == xPtr->data)
}//end of while
if ( xPtr == NULL )
{
mergePtr->nextPtr = yPtr;
}
if ( yPtr == NULL )
{
mergePtr->nextPtr = xPtr;
}
return merge.nextPtr;
}//end of function mergehttps://stackoverflow.com/questions/17844254
复制相似问题