Pārlūkot izejas kodu

添加bitmap优化析构

LinTianxiang 10 mēneši atpakaļ
vecāks
revīzija
90e13e0fac
2 mainītis faili ar 44 papildinājumiem un 22 dzēšanām
  1. 37 17
      tire.cpp
  2. 7 5
      tire.h

+ 37 - 17
tire.cpp

@@ -8,19 +8,42 @@
 #define NODE ADT::Node
 #define ITERATOR ADT::iterator
 
+
+#define INDEX(x) ((const int)(x))
+inline unsigned int lowbit(unsigned int x) {
+	return x & -x;
+}
+
+inline int bit_weight(unsigned int x) {
+	x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+	x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+	x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
+	x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
+	x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff);
+	return (int)x;
+}
+
 // #pragma region Tire<Type>::Node
 TEMPLATE(HOLDER) NODE::Node() {
 
 }
 
 TEMPLATE(HOLDER) NODE::~Node() {
-	for (int i = 0; i < TIRE_NODE_NUMBER; ++i) {
-		if (_next[i] != nullptr) {
-			delete _next[i];
-			_next[i] = nullptr;
+	int index = 0;
+	for (int i = 0; i < BITMAP_NUMBER; ++i) {
+		unsigned int bmap = bitmap[i];
+		// lowbit 取最低非零位
+		// 汉明重量 计算最低非零位位置
+		for (; bmap != 0;) {
+			unsigned int x = lowbit(bmap);
+			int y = bit_weight(x - 1u);
+			delete next[index + y];
+			next[index + y] = nullptr;
+			bmap -= x;
 		}
+		index += (2 << UINT_SIZE);
 	}
-	_value = nullptr;
+	value = nullptr;
 }
 // #pragma endregion
 
@@ -30,24 +53,20 @@ TEMPLATE(HOLDER) ADT::Tire() {
 }
 
 TEMPLATE(HOLDER) ADT::~Tire() {
-	for (int i = 0; i < TIRE_NODE_NUMBER; ++i) {
-		delete _root._next[i];
-		_root._next[i] = nullptr;
-	}
-	_root._value = nullptr;
+	delete _root;
 }
 
 TEMPLATE(typename ITERATOR) ADT::find(const std::string& key) {
-	Node* curr = &_root;
+	Node* curr = _root;
 	Node* next = nullptr;
 	for (const char& ch : key) {
-		next = curr->_next[INDEX(ch)];
+		next = curr->next[INDEX(ch)];
 		if (next == nullptr) {
 			return end();
 		}
 		curr = next;
 	}
-	return curr->_value == nullptr ? end() : iterator(curr->_value);
+	return curr->value == nullptr ? end() : iterator(curr->value);
 }
 
 TEMPLATE(Type&) ADT::operator[](const std::string& key) {
@@ -55,18 +74,19 @@ TEMPLATE(Type&) ADT::operator[](const std::string& key) {
 }
 
 TEMPLATE(typename ITERATOR) ADT::insert(const std::string& key, Type& value) {
-	Node* curr = &_root;
+	Node* curr = _root;
 	Node* next = nullptr;
 	for (const char& ch : key) {
-		next = curr->_next[INDEX(ch)];
+		next = curr->next[INDEX(ch)];
 		if (next != nullptr) {
 			curr = next;
 			continue;
 		}
-		curr = curr->_next[(int)ch] = new Node();
+		curr->bitmap[(int)((unsigned int)ch >> (UINT_SIZE + 1))] |= 0x01u << ((unsigned int)ch & 0x1fu);
+		curr = curr->next[INDEX(ch)] = new Node();
 	}
 	iterator it = _container.append(value);
-	curr->_value = &it;
+	curr->value = &it;
 	return it;
 }
 

+ 7 - 5
tire.h

@@ -5,8 +5,9 @@
 #include "list.cpp"
 #include <string>
 
-#define TIRE_NODE_NUMBER 128
-#define INDEX(x) ((const int)(x))
+const int TIRE_NODE_NUMBER = 128;
+const int UINT_SIZE = sizeof(unsigned int);
+const int BITMAP_NUMBER = TIRE_NODE_NUMBER / UINT_SIZE / 8;
 
 template<typename Type,
 	typename Container = List<Type>>
@@ -16,14 +17,15 @@ template<typename Type,
 			Node();
 			~Node();
 			Node* operator[](const int ch);
-			Node* _next[TIRE_NODE_NUMBER] { nullptr };
-			typename Container::Node* _value = nullptr;
+			Node* next[TIRE_NODE_NUMBER] { nullptr };
+			unsigned int bitmap[BITMAP_NUMBER] = { 0 };
+			typename Container::Node* value = nullptr;
 		};
 
 		typedef typename Container::iterator iterator;
 
 	private:
-		Node _root;
+		Node* _root = new Node();
 		Container _container;
 	public:
 		Tire();