user-0 提问: 【求助】数据结构，c语言的链表的排序问题

回复:
user: user-1
content: 引用 6 楼 u013095718 的回复:[quote=引用 1 楼 user-4 的回复:] 代码中有malloc函数，所以单步调试不了？？ 什么情况  我用的是vc6.0，然后初学，所以每次单步调试到malloc函数，就会弹出一个对话框，Please Enter The Path For DBGHEAP.C.，然后就不知道咋办了……  求大神指教！[/quote] Skip it！

user: user-0
content: 引用 2 楼 yulinlang 的回复:两个问题：  1.     //将链表各结点地址赋给数组P[10]     while(ptr!=NULL)     {         p[i] = ptr;         ptr = ptr->next;     } 循环中i无变化，所以仅仅为p[0]赋值 考虑改为：  while(ptr!=NULL) {         p[i++] = ptr;         ptr = ptr->next; }   2      //根据数组P，重新排列链表     i=0;     head->next = p[i];     while(p[i]->next!=NULL)     {         p[i]->next = p[i+1];         i++;     }      因为数组已排序，原来的结点顺序已打乱，尾结点可能出现在数组的任意位置，所以这样是不对的 考虑改为     //根据数组P，重新排列链表     i=0;     head->next = p[i];     while(i < 9) {         p[i]->next = p[i+1];         i++;     }     p[i]->next = NULL;  第一个问题是手误，程序运行错误和这个问题无关，第二个问题确实没考虑到，我再去试试

user: user-0
content: 引用 3 楼 N_sev7 的回复:“代码中有malloc函数，所以单步调试不了” 这是什么理论 我用的是vc6.0，然后初学，所以每次单步调试到malloc函数，就会弹出一个对话框，Please Enter The Path For DBGHEAP.C.，然后就不知道咋办了……  求大神指教！

user: user-0
content: 引用 1 楼 user-4 的回复:代码中有malloc函数，所以单步调试不了？？ 什么情况  我用的是vc6.0，然后初学，所以每次单步调试到malloc函数，就会弹出一个对话框，Please Enter The Path For DBGHEAP.C.，然后就不知道咋办了……  求大神指教！

user: user-1
content: _CrtDumpMemoryLeaks Dumps all of the memory blocks in the debug heap when a memory leak has occurred (debug version only).  int _CrtDumpMemoryLeaks( void );  Routine Required Header Compatibility  _CrtDumpMemoryLeaks <crtdbg.h> Win NT, Win 95    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBCD.LIB Single thread static library, debug version  LIBCMTD.LIB Multithread static library, debug version  MSVCRTD.LIB Import library for MSVCRTD.DLL, debug version    Return Value  _CrtDumpMemoryLeaks returns TRUE if a memory leak is found; otherwise, the function returns FALSE.  Remarks  The _CrtDumpMemoryLeaks function determines whether a memory leak has occurred since the start of program execution. When a leak is found, the debug header information for all of the objects in the heap is dumped in a user-readable form. When _DEBUG is not defined, calls to _CrtDumpMemoryLeaks are removed during preprocessing.  _CrtDumpMemoryLeaks is frequently called at the end of program execution to verify that all memory allocated by the application has been freed. The function can be called automatically at program termination by turning on the _CRTDBG_LEAK_CHECK_DF bit field of the _crtDbgFlag flag using the _CrtSetDbgFlag function.  _CrtDumpMemoryLeaks calls _CrtMemCheckpoint to obtain the current state of the heap and then scans the state for blocks that have not been freed. When an unfreed block is encountered, _CrtDumpMemoryLeaks calls _CrtMemDumpAllObjectsSince to dump information for all of the objects allocated in the heap from the start of program execution.   By default, internal C run-time blocks (_CRT_BLOCK) are not included in memory dump operations. The _CrtSetDbgFlag function can be used to turn on the _CRTDBG_CHECK_CRT_DF bit of _crtDbgFlag to include these blocks in the leak detection process.  For more information about heap state functions and the _CrtMemState structure, see the Heap State Reporting Functions. For information about how memory blocks are allocated, initialized, and managed in the debug version of the base heap, see Memory Management and the Debug Heap.  Example  /*****************************************************************  *  EXAMPLE  1                                                   *  *  This simple program illustrates the basic debugging features *  *  of the C runtime libraries, and the kind of debug output     *  *  that these features generate.                                *  *****************************************************************/  #include <stdio.h> #include <string.h> #include <malloc.h> #include <crtdbg.h>  // This routine place comments at the head of a section of debug output void OutputHeading( const char * explanation ) {    _RPT1( _CRT_WARN, "\n\n%s:\n**************************************\ ************************************\n", explanation ); }  // The following macros set and clear, respectively, given bits // of the C runtime library debug flag, as specified by a bitmask. #ifdef   _DEBUG #define  SET_CRT_DEBUG_FIELD(a) \             _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #define  CLEAR_CRT_DEBUG_FIELD(a) \             _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #else #define  SET_CRT_DEBUG_FIELD(a)   ((void) 0) #define  CLEAR_CRT_DEBUG_FIELD(a) ((void) 0) #endif   void main( ) {    char *p1, *p2;    _CrtMemState s1, s2, s3;     // Send all reports to STDOUT    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );     // Allocate 2 memory blocks and store a string in each    p1 = malloc( 34 );    strcpy( p1, "This is the p1 string (34 bytes)." );     p2 = malloc( 34 );    strcpy( p2, "This is the p2 string (34 bytes)." );      OutputHeading(        "Use _ASSERTE to check that the two strings are identical" );    _ASSERTE( strcmp( p1, p2 ) == 0 );     OutputHeading(        "Use a _RPT macro to report the string contents as a warning" );    _RPT2( _CRT_WARN, "p1 points to '%s' and \np2 points to '%s'\n", p1, p2 );     OutputHeading(        "Use _CRTMemDumpAllObjectsSince to check the p1 and p2 allocations" );    _CrtMemDumpAllObjectsSince( NULL );     free( p2 );     OutputHeading(        "Having freed p2, dump allocation information about p1 only" );    _CrtMemDumpAllObjectsSince( NULL );     // Store a memory checkpoint in the s1 memory-state structure    _CrtMemCheckpoint( &s1 );     // Allocate another block, pointed to by p2    p2 = malloc( 38 );    strcpy( p2, "This new p2 string occupies 38 bytes.");     // Store a 2nd memory checkpoint in s2    _CrtMemCheckpoint( &s2 );     OutputHeading(        "Dump the changes that occurred between two memory checkpoints" );    if ( _CrtMemDifference( &s3, &s1, &s2 ) )       _CrtMemDumpStatistics( &s3 );     // Free p2 again and store a new memory checkpoint in s2    free( p2 );    _CrtMemCheckpoint( &s2 );     OutputHeading(        "Now the memory state at the two checkpoints is the same" );    if ( _CrtMemDifference( &s3, &s1, &s2 ) )       _CrtMemDumpStatistics( &s3 );     strcpy( p1, "This new p1 string is over 34 bytes" );    OutputHeading( "Free p1 after overwriting the end of the allocation" );    free( p1 );     // Set the debug-heap flag so that freed blocks are kept on the    // linked list, to catch any inadvertent use of freed memory    SET_CRT_DEBUG_FIELD( _CRTDBG_DELAY_FREE_MEM_DF );     p1 = malloc( 10 );    free( p1 );    strcpy( p1, "Oops" );     OutputHeading( "Perform a memory check after corrupting freed memory" );    _CrtCheckMemory( );     // Use explicit calls to _malloc_dbg to save file name and line number    // information, and also to allocate Client type blocks for tracking    p1 = _malloc_dbg( 40, _NORMAL_BLOCK, __FILE__, __LINE__ );    p2 = _malloc_dbg( 40, _CLIENT_BLOCK, __FILE__, __LINE__ );    strcpy( p1, "p1 points to a Normal allocation block" );    strcpy( p2, "p2 points to a Client allocation block" );     // You must use _free_dbg to free a Client block    OutputHeading(        "Using free( ) to free a Client block causes an assertion failure" );    free( p1 );    free( p2 );     p1 = malloc( 10 );    OutputHeading( "Examine outstanding allocations (dump memory leaks)" );    _CrtDumpMemoryLeaks( );     // Set the debug-heap flag so that memory leaks are reported when    // the process terminates. Then, exit.    OutputHeading( "Program exits without freeing a memory block" );    SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ); }  Output  Use _ASSERTE to check that the two strings are identical: ************************************************************************** C:\DEV\EXAMPLE1.C(56) : Assertion failed: strcmp( p1, p2 ) == 0   Use a _RPT macro to report the string contents as a warning: ************************************************************************** p1 points to 'This is the p1 string (34 bytes).' and  p2 points to 'This is the p2 string (34 bytes).'   Use _CRTMemDumpAllObjectsSince to check the p1 and p2 allocations: ************************************************************************** Dumping objects -> {13} normal block at 0x00660B5C, 34 bytes long  Data: <This is the p2 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 32 20 73  {12} normal block at 0x00660B10, 34 bytes long  Data: <This is the p1 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 31 20 73  Object dump complete.   Having freed p2, dump allocation information about p1 only: ************************************************************************** Dumping objects -> {12} normal block at 0x00660B10, 34 bytes long  Data: <This is the p1 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 31 20 73  Object dump complete.   Dump the changes that occurred between two memory checkpoints: ************************************************************************** 0 bytes in 0 Free Blocks. 38 bytes in 1 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 IgnoreClient Blocks. 0 bytes in 0 (null) Blocks. Largest number used: 4 bytes. Total allocations: 38 bytes.   Now the memory state at the two checkpoints is the same: **************************************************************************   Free p1 after overwriting the end of the allocation: ************************************************************************** memory check error at 0x00660B32 = 0x73, should be 0xFD. memory check error at 0x00660B33 = 0x00, should be 0xFD. DAMAGE: after Normal block (#12) at 0x00660B10.   Perform a memory check after corrupting freed memory: ************************************************************************** memory check error at 0x00660B10 = 0x4F, should be 0xDD. memory check error at 0x00660B11 = 0x6F, should be 0xDD. memory check error at 0x00660B12 = 0x70, should be 0xDD. memory check error at 0x00660B13 = 0x73, should be 0xDD. memory check error at 0x00660B14 = 0x00, should be 0xDD. DAMAGE: on top of Free block at 0x00660B10. DAMAGED located at 0x00660B10 is 10 bytes long.   Using free( ) to free a Client block causes an assertion failure: ************************************************************************** dbgheap.c(1039) : Assertion failed: pHead->nBlockUse == nBlockUse   Examine outstanding allocations (dump memory leaks): ************************************************************************** Detected memory leaks! Dumping objects -> {18} normal block at 0x00660BE4, 10 bytes long  Data: <          > CD CD CD CD CD CD CD CD CD CD  Object dump complete.   Program exits without freeing a memory block: ************************************************************************** Detected memory leaks! Dumping objects -> {18} normal block at 0x00660BE4, 10 bytes long  Data: <          > CD CD CD CD CD CD CD CD CD CD  Object dump complete.

user: user-1
content: 仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

user: user-2
content: “代码中有malloc函数，所以单步调试不了” 这是什么理论

user: user-3
content: 两个问题：  1.     //将链表各结点地址赋给数组P[10]     while(ptr!=NULL)     {         p[i] = ptr;         ptr = ptr->next;     } 循环中i无变化，所以仅仅为p[0]赋值 考虑改为：  while(ptr!=NULL) {         p[i++] = ptr;         ptr = ptr->next; }   2      //根据数组P，重新排列链表     i=0;     head->next = p[i];     while(p[i]->next!=NULL)     {         p[i]->next = p[i+1];         i++;     }      因为数组已排序，原来的结点顺序已打乱，尾结点可能出现在数组的任意位置，所以这样是不对的 考虑改为     //根据数组P，重新排列链表     i=0;     head->next = p[i];     while(i < 9) {         p[i]->next = p[i+1];         i++;     }     p[i]->next = NULL;

user: user-4
content: 代码中有malloc函数，所以单步调试不了？？ 什么情况

user: user-0
content: 引用 4 楼 zhao4zhong1 的回复:仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //  谢谢啦，很详细清晰，我去研究下