创建一个链接列表,该列表以升序存储项目或以该顺序打印

时间:2019-03-09 20:35:46

标签: c pointers linked-list

我这里有一个工作的链表,该链表用于存储数字和添加的数字的计数,但是我要解决的问题是了解如何更改此数字,以便它不会仅按输入顺序添加数字,是否可以轻松更改和解决此问题,或者可以更改打印功能来为我执行此功能?

代码

void KnapsackPrint(const listitemptr *knapsack){
   if(*knapsack==NULL)
       printf("knapsack: \n");
   else{
       listitemptr temp=*knapsack;
       while(temp!=NULL){
           printf("knapsack: %d (%d), ",temp->item,temp->count);
           temp=temp->next;
       }
       printf("\n");
   }
}

        listitemptr KnapsackAdd(listitemptr *knapsack, int item){
   if(*knapsack==NULL){//empty list
       listitemptr newest= malloc(sizeof(struct listitem));
       newest->item=item;
       newest->count=1;
       newest->next=NULL;
       *knapsack = newest;
       return newest;
   }else{
       listitemptr current=*knapsack;
       listitemptr prev=NULL;
       while(current!=NULL){
           if(current->item == item){
               current->count=current->count+1;
               break;
           }else if(current -> item > item){
               listitemptr new_node = malloc(sizeof(struct listitem));
               new_node-> item = item;
               new_node-> count= 1;
               new_node-> next = current;
               if(prev != NULL ){
                   prev ->next = new_node;
               }else {
                   current = new_node;
                   break;
               }

           }
           prev=current;
           current=current->next;
       }
       if(current==NULL){
           listitemptr newest= malloc(sizeof(struct listitem));
           newest->item=item;
           newest->count=1;
           newest->next=NULL;
           prev->next=newest;
           return newest;
       }
       return current;
   }
}

Knapsack.h和definitons

/* knapsack.h
 * implements simple knapsack data structure as a linked list 
 * NOTE: a function may update the value of input argument *knapsack if it changes the first node of the knapsack to another node. Such a change include the case when an item is added to an empty knapsack
 */

/* pointer to linked list node data structure */
typedef struct listitem* listitemptr;
/* data structure to use as linked list nodes */
struct listitem {
  int item;           // actual int item
  unsigned int count; // number of the same item in the knapsack; should be >= 1
  listitemptr next;   // pointer to next item 
};

/*
 * adds an item to a knapsack. Nodes should be in ascending order. You must simply increase the "count" if the item already exist in the knapsack; "count" must be set to 1 for previously-nonexisting items
 * @param knapsack: pointer to a listitemptr, itself pointing to the first item in a knapsack; NULL if knapsack has not been created yet 
 * @param item: integer item to add
 * @return pointer to the listitem added/updated; NULL if unsuccessful 
 */
listitemptr KnapsackAdd(listitemptr *knapsack, int item);

/*
 * removes a value from a knapsack; must update the "count" and delete the associated listitem when count becomes 0 
 * @param knapsack: [see KnapsackAdd() params]; updated to NULL if knapsack becomes empty
 * @param item: integer item to remove
 * @return 0 if successful, -1 otherwise (when item not found or knapsack is empty)
 */
int KnapsackRemove(listitemptr *knapsack, int item);

/*
 * prints integer items (in ascending order) and their counts in a knapsack
 * @param knapsack: [see KnapsackAdd() params]
 * @stdout: for example, "" (nothing) when knapsack==NULL, or "-125 (4), 10 (1), 26 (2)" when items include four of -125, one of 10, and two of 26
 * @return void
 */
void KnapsackPrint(const listitemptr *knapsack);

/*
 * returns count of a specific item in a knapsack
 * @param knapsack: [see KnapsackAdd() params]
 * @param item: integer item to search for
 * @return item count, or 0 if it does not exist
 */
unsigned int KnapsackItemCount(const listitemptr *knapsack, int item);

/*
 * total count of items in the knapsack
 * @param knapsack: [see KnapsackAdd() params]
 * @return total item count. For example, 7 in case the items are "-125 (4), 10 (1), 26 (2)" (see SnapsackPrint() description)
 */
unsigned int KnapsackSize(const listitemptr *knapsack);

**电流输出给定2 1 **

knapsack: 2(1) 1(1)

**给定的期望输出为2 1 **

knapsack: 1(1) 2(1)

1 个答案:

答案 0 :(得分:1)

您在正确的轨道上。现在,您的代码可以很好地用于增加现有项目的数量并添加新项目。这是伪代码中的样子(强烈建议您将previous重命名为current,将temp重命名为previous,然后在这种假设下继续执行我的代码-使插入和遍历的推理变得容易得多):

function KnapsackAdd(knapsack, item) {
    if knapsack is empty {
        make a new knapsack with one item in it
    }
    else { // there are already items in the knapsack
        current = knapsack head
        prev = null

        while current != null {
            if current->item == item {
                current->count++
                break
            }

            previous = current
            current = current->next
        }

        // we're at the end of the list and didn't find the item
        if current == null {
            add new item to end of list
        }
    }
}

如何修改此属性以添加项目,以便我们保留排序的顺序?通过在遍历期间添加另一个比较,我们可以检查当前节点是否大于我们要插入的数目。如果是这样,我们就知道到达了正确的插入点:

function KnapsackAdd(knapsack, item) {
    if knapsack is empty {
        make a new knapsack with one item in it
    }
    else { // there are already items in the knapsack
        current = knapsack head
        prev = null

        while current != null {
            if current->item == item {
                current->count++
                break
            }
            else if current->item > item { // we're at the sorted insertion point!
                make new_node(item: item, count: 1, next: current)

                if prev != null { // we're inserting in the middle of the list
                    prev->next = new_node
                }
                else { // we're inserting at the beginning of the list
                       // so we need to update the head reference
                    set knapsack pointer to new_node
                }

                break                 
            }

            previous = current
            current = current->next
        }

        // we're at the end of the list and didn't find the item
        if current == null {
            add new item to end of list
        }
    }
}

我们来看一个例子:

knapsack.add(5)  // knapsack is [5]

knapsack.add(3)  // when iterating, we see that 5 > 3 and engage the new code
                 // block. We must update the head. knapsack is now [3 -> 5]

knapsack.add(7)  // knapsack is [3 -> 5 -> 7]. The new code block is not executed.

knapsack.add(6)  // when iterating, we see that 7 > 6 and engage the 
                 // new code block. No need to update the head; we use the
                 // previous element to link in the new 6 node.
                 // knapsack is [3 -> 5 -> 6 -> 7].

希望这足以说服您,如果我们从一个空列表开始并且始终使用此排序方案进行插入,则可以保证列表排序。

时间复杂度与以前相同:O(n)。