【问题标题】:Creating a array from a linked list and sorting that array C从链表创建一个数组并对该数组进行排序 C
【发布时间】:2016-05-14 14:26:56
【问题描述】:

有人告诉我,对链表进行排序的最佳方法是将该链表复制到一个数组中并对该数组进行排序。

#define SIZE 7000

所以我的链表:

typedef struct no{

    char *nome;
    int count;
    struct no * prox;
}*link;

我的数组:

typedef struct MyArray 
{
    char name[141];
    int count;
}MyArray;

MeuArray v[SIZE];

现在我的创建数组函数:

void create_array()
{
link tmp = head;
int cont = 0;
int i;

while (tmp != NULL)
    {
        strcpy(v[cont].nome, tmp->nome);
        v[cont].count = tmp->count;
        tmp = tmp->prox;
        cont++;
    }
for (i = 0; i < SIZE; i++)
    printf("%s %d\n", v[i].nome, v[i].count);
}

不知道这是否正确。 现在我不知道哪个是最好的/最快的。 qsort 或其他。 如果是qsort:

int compare(struct MeuArray *elem1, struct MeuArray *elem2)
{
if ( elem1->count < elem2->count)
  return -1;

else if (elem1->count > elem2->count)
  return 1;

else
{
    if (strcmp(elem1->name, elem2->name) > 1)
        return 1;
    else
         return -1;
 }
}

我也尝试过这种方式(排序我的链表):

void insertionSort(link current)
{   
link head = current;
link inserP = head;
current = current->prox;
while (current != NULL)
{
    inserP = head;

    while (inserP != current)
     {
        if (inserP->count > current->count)
        {
            int temp = current->count;
            current->count = inserP->count;
             inserP->count = temp;
        }
        else /* if (inserP->count < current->count) */
            inserP = inserP->prox;

        /*else
            {
                if (strcmp(inserP->name, current->name) > 0)
                {
                    char temp2 = strcpy(temp2, current->name);
                    strcpy(current->name, inserP->name);
                    strcpy(inserP->name, temp2);
                 }
                 else
                     inserP = inserP->prox;
            } */
         }
    }
    current = current->prox;
}

与:

link head = NULL;

感谢任何帮助。

编辑

我在 qsort 中我想先按数量比较,然后按名称比较。 问题是我只能按计数排序。 之后如何按名称排序?

代码:

int compare (const void * a, const void * b)
{

MeuArray *MeuArrayA = (MeuArray *)a;
MeuArray *MeuArrayB = (MeuArray *)b;

if ( MeuArrayB->count > MeuArrayA->count )
    return 1;
else if ( MeuArrayB->count < MeuArrayA->count )
    return -1;
else
{
    if (strcmp(MeuArrayB->nome, MeuArrayA->nome))
        return 1;
    else
        return -1;  
}
}

【问题讨论】:

  • 调试器......................
  • 你的链接列表的内容是什么?为什么它有一个计数变量?
  • 你的问题漏掉了一个问题 ;-) 你的问题是什么?代码是否产生错误或不正确的结果?您尝试过哪些输入值?
  • 存储指向指针数组的指针。然后 qsort。
  • 我的问题是。如果这是如何从链表创建数组以及如何实现 qsort。或者有更好/更快的方法。

标签: c arrays sorting linked-list


【解决方案1】:

如果您希望选择不必使用数组,但仍需要快速排序,这里是链表自下而上合并排序的示例,使用指向节点的小型(26 到 32)指针数组.这通常是最快的算法,并且通常是 C++ std::list::sort() 的实现方式。在我的系统(Intel 2600K,3.4 ghz)上,它可以在不到一秒的时间内对包含 400 万个节点的链表进行排序。

typedef struct NODE_{
struct NODE_ * next;
int data;
}NODE;

/* prototype */
NODE * MergeLists(NODE *pSrc1, NODE *pSrc2);

/* sort list using array of pointers to first nodes of list   */
/* aList[i] = NULL or ptr to list with 2 to the power i nodes */

#define NUMLISTS 32                 /* size of array */
NODE * SortList(NODE *pList)
{
NODE * aList[NUMLISTS];             /* array of lists */
NODE * pNode;
NODE * pNext;
int i;
    if(pList == NULL)               /* check for empty list */
        return NULL;
    for(i = 0; i < NUMLISTS; i++)   /* zero array */
        aList[i] = NULL;
    pNode = pList;                  /* merge nodes into array */
    while(pNode != NULL){
        pNext = pNode->next;
        pNode->next = NULL;
        for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
            pNode = MergeLists(aList[i], pNode);
            aList[i] = NULL;
        }
        if(i == NUMLISTS)           /* don't go past end of array */
            i--;
        aList[i] = pNode;
        pNode = pNext;
    }
    pNode = NULL;                   /* merge array into one list */
    for(i = 0; i < NUMLISTS; i++)
        pNode = MergeLists(aList[i], pNode);
    return pNode;
}

/* mergelists -  compare uses src2 < src1           */
/* instead of src1 <= src2 to be similar to C++ STL */

NODE * MergeLists(NODE *pSrc1, NODE *pSrc2)
{
NODE *pDst = NULL;                  /* destination head ptr */
NODE **ppDst = &pDst;               /* ptr to head or prev->next */
    if(pSrc1 == NULL)
        return pSrc2;
    if(pSrc2 == NULL)
        return pSrc1;
    while(1){
        if(pSrc2->data < pSrc1->data){  /* if src2 < src1 */
            *ppDst = pSrc2;
            pSrc2 = *(ppDst = &(pSrc2->next));
            if(pSrc2 == NULL){
                *ppDst = pSrc1;
                break;
            }
        } else {                        /* src1 <= src2 */
            *ppDst = pSrc1;
            pSrc1 = *(ppDst = &(pSrc1->next));
            if(pSrc1 == NULL){
                *ppDst = pSrc2;
                break;
            }
        }
    }
    return pDst;
}

【讨论】:

  • 感谢您的回答。我会试一试的。
【解决方案2】:

如果要对链接列表进行排序,则无需将其转换为数组。您可以有效地在链接列表中进行操作

while(t1!=NULL)
 {
  count++;
  t1=t1->ptr;
 }
 for(i=0;i<count;i++)
  {
   t1=START;
   for(j=0;j<count-i-1;j++)
    {
      if(t1->info>(t1->ptr)->info)
       {
 int temp=t1->info;
 t1->info=(t1->ptr)->info;
 (t1->ptr)->info=temp;
       }
       t1=t1->ptr;
    }
  }

使用冒泡排序 欲了解更多信息click here

【讨论】:

  • 如果我想使用它,我该如何改变它,让它先从count排序,然后再从nome排序?什么是 START?
  • IDK START 是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-26
相关资源
最近更新 更多