简体   繁体   English

初学者从结构数组中删除第一个元素(C)

[英]Beginner Removing first element from an array of structs (C)

I have an array of structs (actually it's a heap array sorted by priority).我有一个结构数组(实际上它是一个按优先级排序的堆数组)。

 typedef struct {
    char name[MAX_CHARACTERS+1];
    int priority;
} person;
person p[MAX_HEAPSIZE+1];

and want to remove the first element in the array.并想要删除数组中的第一个元素。 I'm not sure how or what command to use.我不确定如何使用或使用什么命令。

So far, I've been doing到目前为止,我一直在做

void remove(){
    swap(0, heapsize-1);
    strcpy(p[heapsize-1].name, p[MAX_HEAP_SIZE+1].name);
    p[heapsize-1].priority = p[MAX_HEAP_SIZE+1].priority;
}

this swaps the first and last non-empty element in the array.这将交换数组中的第一个和最后一个非空元素。 Then it tries to copy the data at an empty element to the last non-empty element (element i want to remove) in the array.然后它尝试将空元素处的数据复制到数组中的最后一个非空元素(我要删除的元素)。

but I think it only copies the memory positions.但我认为它只复制 memory 位置。 Is there something simple where I can do有什么简单的地方我可以做

p[0] = NULL? p[0] = NULL?

An array is a continuous block of memory.数组是 memory 的连续块。 So if you want to remove the first element, you have to move all the following elements towards the beginning by one element:因此,如果要删除第一个元素,则必须将以下所有元素向开头移动一个元素:

void remove(void)
{
    memmove(&p[0], &p[1], (MAX_HEAPSIZE - 1) * sizeof(person));
}

This is pretty inefficient.这是相当低效的。 Popping the first element is a common operation with a heap, so you'd usually do it the other way around - remove the last element of an array - which is very fast, because the other elements of the array aren't affected.弹出第一个元素是堆的常见操作,因此您通常会以相反的方式执行 - 删除数组的最后一个元素 - 这非常快,因为数组的其他元素不受影响。

void remove(void)
{
    heapsize--;
}

heapsize can then be used as the index of the top element of the heap (assuming you preserve the heap property, of course). heapsize然后可以用作堆顶部元素的索引(当然,假设您保留了堆属性)。

If you want to overwrite the first element of the array with the last one and zero out the memory of the last element, which is not used anymore, you can use memcpy and memset:如果你想用最后一个覆盖数组的第一个元素并将最后一个元素的 memory 清零,不再使用,你可以使用 memcpy 和 memset:

void remove(void)
{
    memcpy(&p[0], &p[heapsize - 1], sizeof(person));
    memset(&p[heapsize - 1], 0x00, sizeof(person));
}

Zeroing out the memory of the last element is not strictly necessary, though, because you shouldn't be accessing it in the first place.但是,将最后一个元素的 memory 清零并不是绝对必要的,因为您不应该首先访问它。 Instead of overwriting the first element with the last using memcpy, it can also be done with strcpy and assignment of the priority (like in your remove );除了使用 memcpy 用最后一个元素覆盖第一个元素,还可以使用strcpy和分配优先级来完成(就像在你的remove一样); using memcpy is simply easier.使用 memcpy 更简单。

It sounds like you are trying to implement a heap sort.听起来您正在尝试实现堆排序。 You don't actually need to "remove" the first element of the heap, or even the last one.您实际上不需要“删除”堆的第一个元素,甚至最后一个元素。

Instead, the algorithm is to copy the values from the the first element (the element with the highest priority) for output, then to copy the node from the "end" of the array to the first position in preparation to bubble it down into the correct position.相反,算法是从 output 的第一个元素(具有最高优先级的元素)复制值,然后将节点从数组的“末尾”复制到第一个 position 准备将其冒泡到正确的 position。 The "end" of the array is indicated by the current heap_size.数组的“结束”由当前 heap_size 指示。

To "remove" the last item of the array, just reduce the heap_size by 1.要“删除”数组的最后一项,只需将 heap_size 减 1。

I vaguely recall that the bubbling down is accomplished by checking the priorities of the children on the moving item, and then swapping it with the one with the highest priority.我依稀记得冒泡是通过检查子项在移动项目上的优先级,然后将其与具有最高优先级的那个交换来完成的。 Repeat this on the moved item until the item is of equal or higher priority to its children.对移动的项目重复此操作,直到该项目与其子项具有相同或更高的优先级。

The trick to find the children of an item is easy: they are the nodes at 2*i and 2*i+1, where the array starts at 1 instead of 0. (Would it be 2*(i+1)-1 and 2*(1+1) for 0-based arrays? Check my math, please. Or just waste one element of the array to keep the math simple.)找到一个项的子项的技巧很简单:它们是 2*i 和 2*i+1 处的节点,其中数组从 1 开始而不是 0。(是否为 2*(i+1)-1和 2*(1+1) 表示基于 0 的 arrays?请检查我的数学。或者只是浪费数组的一个元素以保持数学简单。)

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

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