链表的数组实现 令链表的所有元素在数组中保持紧凑 《算法导论》10.3-4
Posted meixiaogua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表的数组实现 令链表的所有元素在数组中保持紧凑 《算法导论》10.3-4相关的知识,希望对你有一定的参考价值。
- 让长度为m的链表的所有元素占用数组的前m个位置。
- 假设数组总长度为SIZE,用一个变量freeHead记录空闲表的起始下标, 则[freeHead, SIZE)的范围内的对象全部属于自由表。用一个Object对象list表示链表头。
- 当从链表的任意位置删除元素时,比如下标为pos的元素,那么就让下标为pos和freeHead-1的元素互换在链表中的位置,然后删除互换后下标为freeHead-1的元素,也就相当于删除了互换前下标为pos的元素,这样一来,就可以保证所删除元素的位置始终是自由表头freeHead的前一个位置,于是保持了自由表中元素下标的连续性。freeHead将数组元素分为前半部分的链表元素和后半部分的自由元素。
#include <cassert>
#include <iostream>
using namespace std;
struct Object
{
int prev;
int key;
int next;
};
constexpr int SIZE = 10;
Object array[SIZE];
int freeHead = 0;
Object list;
void Init()
{
list.prev = -1;
list.next = -1;
}
int AllocateObject()
{
if(freeHead == SIZE)
return -1;
array[freeHead].prev = array[list.next].prev;
array[freeHead].next = array[list.prev].next;
array[list.next].prev = freeHead;
array[list.prev].next = freeHead;
return freeHead++;
}
void FreeObject(int pos)
{
assert(pos >= 0 && pos < freeHead);
int listTail = --freeHead;
//delete array[pos] from list
array[array[pos].prev].next = array[pos].next;
array[array[pos].next].prev = array[pos].prev;
//move array[listTail] to array[pos]
array[pos] = array[listTail];
int listTailPrev = array[listTail].prev;
int listTailNext = array[listTail].next;
array[listTailPrev].next = pos;
array[listTailNext].prev = pos;
}
void Test()
{
Init();
for(int i = 0; i != SIZE; ++i)
cout << AllocateObject() << " ";
cout << endl; //占用0~9全部元素
cout << AllocateObject() << endl;// -1
for(int i = 0; i != SIZE/2; ++i)
FreeObject(i); //释放下标为0 1 2 3 4的5个元素
for(int i = 0; i != SIZE/2; ++i)
cout << AllocateObject() << " ";
cout << endl; //由于链表中元素保持紧凑,所以实际空闲下来的元素下标为5 6 7 8 9
}
//运行结果为
0 1 2 3 4 5 6 7 8 9
-1
5 6 7 8 9
以上是关于链表的数组实现 令链表的所有元素在数组中保持紧凑 《算法导论》10.3-4的主要内容,如果未能解决你的问题,请参考以下文章