繁体   English   中英

用指针随机播放c中的链接列表

[英]Shuffle linked list in c with pointers

我试图在C链表。 我正在考虑通过遍历整个列表来做到这一点,对于每个对象,我将尝试随机分配索引并在它们之间交换。 似乎代码可以正常工作,但是经过几次我运行代码后,列表的一部分似乎已经消失了,有时候我被应用程序踢了出去。

这是代码:

void main() {
    Song* head = createSong(1, "aaaa", "aaaa");
    Song* song2 = createSong(2, "bbbb", "bbbb");
    Song* song3 = createSong(3, "cccc", "cccc");
    addSongToTheEndOfTheList(head, song2);
    addSongToTheEndOfTheList(head, song3);
    printPlaylist(head);
    shuffleList(head);
    printPlaylist(head);
    //freePlaylist(head);
}
int countList(Song* head) {
    Song* currentSong = head;
    int i = 0;
    if (currentSong)
    {
        while (currentSong->next)
        {
            currentSong = currentSong->next;
            i++;
        }       
        i++;
    }
    return i;
}
void swapSong(Song* head,Song* Source, int id) {
    Song* tempSong = (Song*)malloc(sizeof(Song));
    Song* currentSong = head;
    while(currentSong && currentSong->id != id){
        currentSong = currentSong->next;
    }
    if (currentSong) {
        tempSong->id = currentSong->id;
        tempSong->name = currentSong->name;
        tempSong->artist = currentSong->artist;
        tempSong->next = currentSong->next;
        currentSong->id = Source->id;
        currentSong->name = Source->name;
        currentSong->artist = Source->artist;
        currentSong->next = Source->next;
        Source->id = tempSong->id;
        Source->name = tempSong->name;
        Source->artist = tempSong->artist;
        Source->next = tempSong->next;
        free(tempSong);
    }
    else {
        printf("The list is empty.");
    }

}
void shuffleList(Song* head) {
    Song* currentSong = head;
    int listLength = countList(head);
    int randNum;
    srand(time(NULL));
    if (currentSong) {
        for (int i = 1; currentSong;i++) {
            swapSong(head, currentSong, rand()%listLength+1);
            currentSong = currentSong->next;
        }
    }
    else {
        printf("The list is empty.");
    }
}

完整的代码在这里: https : //pastebin.com/fSS3rrTv

希望你能帮助我解决。 谢谢!

错误在于swapSong 交换列表中的元素有两种可能的方法:

  • 您交换数据并且不触摸next指针
  • 或者您不触摸数据添加更改指针

前者对于内部数据很少的单链列表更简单(这是您的用例),而后者对于双链列表更简单。

在这里,只需将swapSong更改为:

void swapSong(Song* head,Song* Source, int id) {
    Song* tempSong = (Song*)malloc(sizeof(Song));
    Song* currentSong = head;
    while(currentSong && currentSong->id != id){
        currentSong = currentSong->next;
    }
    if (currentSong) {
        tempSong->id = currentSong->id;
        tempSong->name = currentSong->name;
        tempSong->artist = currentSong->artist;
        //tempSong->next = currentSong->next;
        currentSong->id = Source->id;
        currentSong->name = Source->name;
        currentSong->artist = Source->artist;
        //currentSong->next = Source->next;
        Source->id = tempSong->id;
        Source->name = tempSong->name;
        Source->artist = tempSong->artist;
        //Source->next = tempSong->next;
        free(tempSong);
    }
    else {
        printf("The list is empty.");
    }

}

顺便说一句,在Song结构中, id声明为int * ,而用作int 更改为以下内容以删除一些警告:

typedef struct Song {
    int id;
    char* name;
    char* artist;
    struct Song* next;
}Song;

正如@ 500-InternalServerError所注意到的那样,您不需要在swapSong分配任何swapSong :只需使用本地结构即可:

void swapSong(Song* head,Song* Source, int id) {
    Song* currentSong = head;
    while(currentSong && currentSong->id != id){
        currentSong = currentSong->next;
    }
    if (currentSong) {
        Song tempSong = *currentSong;
        currentSong->id = Source->id;
        currentSong->name = Source->name;
        currentSong->artist = Source->artist;
        Source->id = tempSong.id;
        Source->name = tempSong.name;
        Source->artist = tempSong.artist;
    }
    else {
        printf("The list is empty.");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM