C语言 链表头指向冒泡排序后的第三个节点,函数中的链表是正确的,但在main中打印时,链表较短

x8diyxa7  于 2023-04-05  发布在  其他
关注(0)|答案(2)|浏览(83)

这是一个编程任务,我们必须通过'id'对一个单链表进行排序。我们给出了不能更改的函数原型。在我的'sortEmployee'函数中,当我在函数内部打印时,列表被正确排序,但是当我尝试在排序后在main内部打印原始列表时,列表变短了。我相信头部不知何故被指向了函数的其他地方。
我不允许修改函数原型。教授希望我们从函数内部打印排序列表,而不修改通过sortEmployee()函数传递的main中的链表。因此链表应该与排序后的链表相同。
我为这个活动绞尽脑汁太久了,累坏了。

struct employee     // linked list structure
{
   char fname[MAX_LENGTH];
   char lname[MAX_LENGTH];
   int empId;              
   int numDependents;
   char  ** dependents;
   struct employee * nextEmployee;          
};
void sortEmployee (struct employee * head){     // sorting function

    if(head == NULL){
        printf("Error!\n");
        return;
    }

    a3Emp * current, *sorted, *previous;
    a3Emp * newHead = head;

    int swapped = 1;

    while(swapped) {
        swapped = 0;
        previous = NULL;
        current= newHead;

        while(current->nextEmployee != NULL) {
            sorted = current->nextEmployee;
            if(current->empId > sorted->empId) {
                current->nextEmployee = sorted->nextEmployee;
                sorted->nextEmployee = current;
                if(previous == NULL) {
                    newHead= sorted;
                } else {
                    previous->nextEmployee = sorted;
                }
                previous = sorted;
                swapped = 1;
            } else {
                previous= current;
                current = current->nextEmployee;
            }
        }
    }

    printf("Employees sorted by Employee Id: \n");
    printLL(newHead);

}

void printLL (struct employee * head){    // print function

    a3Emp *newTemp = head;                   

    int count = 0;

    if(newTemp == NULL){
        printf("List not found! Please try again\n");
    }

    while(newTemp != NULL){                    

        printf("\nEmployee #%d: \n", count + 1 );

        printf("\tEmployee id: %d\n", newTemp ->empId);
        printf("\tFirst Name: %s\n", newTemp ->fname);
        printf("\tLast Name: %s\n", newTemp ->lname);

        printf("\tDependents: ");

        int i = 0;
        if(newTemp ->numDependents == 0){
                printf("N/A \n");
            } else {

            while(i < newTemp ->numDependents){

                if(i == newTemp ->numDependents - 1){
                    printf("%s\n", newTemp ->dependents[i]);
                } else {
                    printf("%s, ", newTemp ->dependents[i]);
                }

                i++;

            }
        }

        newTemp = newTemp ->nextEmployee;              

        count++;

    }

    printf("There are currently %d employees.\n", count);

}

当我在main中调用printLL(head)时,得到的是:

Employee #1:
        Employee id: 402
        First Name: Eugene
        Last Name: Martin
        Dependents: Exe, Why

Employee #2:
        Employee id: 809
        First Name: Sania
        Last Name: Mirza
        Dependents: Bee, Kay

Employee #3:
        Employee id: 106
        First Name: Andre
        Last Name: Sampras
        Dependents: Ef, Zed

Employee #4:
        Employee id: 100
        First Name: Roger
        Last Name: Nadal
        Dependents: Eye, Jee

Employee #5:
        Employee id: 524
        First Name: Johnny
        Last Name: Boy
        Dependents: kid, kidster

当我在main中调用sortEmployee(head)时,输出如下:

Employee #1:
        Employee id: 100
        First Name: Roger
        Last Name: Nadal
        Dependents: Eye, Jee

Employee #2:
        Employee id: 106
        First Name: Andre
        Last Name: Sampras
        Dependents: Ef, Zed

Employee #3:
        Employee id: 402
        First Name: Eugene
        Last Name: Martin
        Dependents: Exe, Why

Employee #4:
        Employee id: 524
        First Name: Johnny
        Last Name: Boy
        Dependents: kid, kidster

Employee #5:
        Employee id: 809
        First Name: Sania
        Last Name: Mirza
        Dependents: Bee, Kay

但是当我在调用sortEmployee(head)之后在main中调用printLL(head)时,输出变为:

Employee #1:
        Employee id: 402
        First Name: Eugene
        Last Name: Martin
        Dependents: Exe, Why

Employee #2:
        Employee id: 524
        First Name: Johnny
        Last Name: Boy
        Dependents: kid, kidster

Employee #3:
        Employee id: 809
        First Name: Sania
        Last Name: Mirza
        Dependents: Bee, Kay

输出应该和我第一次调用printLL(head)的时候一样。有人能帮我解决这个问题吗?谢谢!

bpzcxfmw

bpzcxfmw1#

要在不修改链接的情况下对列表进行排序,需要将排序顺序保存到一个单独的数组中,这是未经测试的,但我相信它会是这样的:

bool containsEmpID(int empId, struct employee ** sorted, int count){
   int i = 0;
   bool found = false;
   while (i < count){
      if((*sorted)[i]->empId == empId){
         found = true;
         i = count;
      }
      i++;
   }
   return found;
}

void sortEmployee (struct employee * head){     // sorting function

    if(head == NULL){
        printf("Error!\n");
        return;
    }

    int count = 0;
    a3Emp * temp = head;

    while(temp != NULL){  
        temp = temp ->nextEmployee;              
        count++;
    }

    a3Emp * sorted[count];
    int sortedIndex = 0;

    a3Emp * current;
    sorted[0] = head; 
   

    while(sortedIndex < count) {

        current = head; 
        temp = current->nextEmployee;
            
        while(temp != NULL) {
            if(current->empId > temp->empId
               && !containsEmpID(temp->empId, sorted, sortedIndex+1) {
                current = temp;           
            }
            temp = temp->nextEmployee;
        }
        sorted[sortedIndex++] = current;
    }

    printf("Employees sorted by Employee Id: \n");
    printLL(sorted);

}

需要将printLL更改为void printLL(struct employee ** sorted, int count),我假设这个函数是自己制作的,并且可以在sort函数中调用它时进行更改。然后需要循环遍历数组并打印每个employee结构。

acruukt9

acruukt92#

要演示此问题的一个解决方案,请执行以下操作:

// Abridged struct for this demo. Note use of "typedef"
typedef struct employee { 
    int empId;
    char *fname;
    struct employee *next;
} emp_t;

// A "generic" function to show the fields of a record
void printEmp( int n, emp_t *p ) {
    printf("\nEmployee #%d: \n", n + 1 );
    printf("\tEmployee id: %d\n", p->empId);
    printf("\tFirst Name: %s\n", p->fname);
}

// The LL approach separating "structure" from "data"
void printLL(emp_t *head) {
    for( int count = 0; head; head = head->next )
        printEmp( count++, head );
}

// qsort is lousy for small arrays, but it's reliable
int cmp( const void *a, const void *b ) {
    emp_t *pa = *(emp_t**)a, *pb = *(emp_t**)b;
    return pa->empId - pb->empId;
}

// Build an array of pointers from the LL, sort, display and discard.
void sortShow( emp_t *head ) {
    int i = 0;
    emp_t *p;

    for( p = head; p; p = p->next )
        i++;

    emp_t **arr = malloc( i * sizeof *arr ); // or a VLA if your compiler can...

    i = 0;
    for( p = head; p; p = p->next )
        arr[i++] = p;

    qsort( arr, i, sizeof arr[0], cmp );

    puts( "Now sorted by ID:" );
    for( int j = 0; j < i; j++ )
        printEmp( j, arr[j] );

    free( arr );
}

int main( void ) {
    emp_t emps[] = { // hardwired abridged data to play with
        { 402, "Eugene" },
        { 809, "Sania" },
        { 106, "Andre" },
        { 100, "Roger" },
        { 524, "Johnny" },
    };
    const int nemps = sizeof emps/sizeof emps[0];

    for( int i = 1; i < nemps; i++ ) // connect up LL pointers
        emps[i-1].next = &emps[i];

    printLL( &emps[0] ); // As loaded

    sortShow( &emps[0] ); // sorted and printed

    return 0;
}

今天没什么要做的…

相关问题