markdown:
Bài giảng cho lớp cấu trúc dữ liệu. Bạn nào rảnh đọc thì góp ý giùm, nhất là phần C++.
Bài trước: [thuật toán tồi tệ nhất trong lịch sử nhân loại]
Bài sau: [lớp Vector và phân tích khấu hao].
### 1. Binary search
Searching for a key (int, say) in a vector of integers is a simple linear-time procedure:
/** * ----------------------------------------------------------------------------- * scan a vector, search for the key * ----------------------------------------------------------------------------- */ bool linear_search(vector<int> vec, int key) { for (size_t i=0; i<vec.size(); i++) { if (key == vec[i]) return true; } return false; }
However, if the input vector is already sorted, we can do better using binary search:
/** * ----------------------------------------------------------------------------- * check the middle element, search the left or right accordingly * ----------------------------------------------------------------------------- */ bool binary_search(vector<int> sorted_vec, int key, size_t left, size_t right) { while (left <= right) { // the following will cause problems if you do // mid = (left+right)/2, due to potential integer overflow size_t mid = left + (right - left)/2; if (key > sorted_vec[mid]) left = mid+1; else if (key < sorted_vec[mid]) right = mid-1; else return true; } return false; }
Let
denote the run time for binary search, it is not hard to write down a recurrence for it:
Then, using a method similar to the analysis of
fib4() algorithm, we can guess the solution of
.
Binary search is exponentially faster than linear search, given that the input array or vector is already sorted. Hence, if we are going to do a lot of searches over the same input, it would be wise to sort the input once and for all. (Later on in the semester, we will discuss other data structures which can help speed up multiple searches over the same data.) To be specific, suppose we perform
searches over an array of size
, then the total amount of time it takes is
if each search is linear. Now, if we pre-sort the input in time
for some function
, then the total time it takes is
, which is potentially much faster than
for
large. We discuss several well-known sorting algorithms next.
[This website](http://www.sorting-algorithms.com/) has nice annimations of the sorting algorithms we discuss here.
### 2. Insertion sort
[Insertion sort](http://en.wikipedia.org/wiki/Insertion_sort) is based on the following idea. Say the input is
A[0..n-1]. For each
i from
1 to
n-1, we find the right place in
A[0...i-1] (which is already sorted) to
*insert*
A[i].
/** * ----------------------------------------------------------------------------- * The Insertion Sort algorithm * for each i from 1 to n-1, insert vec[i] to the right place in the prefix * ----------------------------------------------------------------------------- */ void insertion_sort(vector<int> &vec) { int temp, j; for (int i=1; i<vec.size(); i++) { temp = vec[i]; j = i-1; while (j >= 0 && vec[j] > temp) { vec[j+1] = vec[j]; j--; } vec[j+1] = temp; } }
In the worst-case,
A[i] shifts
i elements in the prefix to the right, and inserts itself in position
0. Hence, the total running time is big-O of
. Overall, the worst-case run time for insertion sort is
. If the input is already sorted (in ascending order), then no data movement is made and there are only at most
comparisons. That is the best-case scenario. The worst-case input is the inversedly sorted input, which requires both
moves (data movements) and
comparisons.
Two nice properties of insertion sort are: (1) the algorithm only uses
extra space (this is called an
[in-place algorithm](http://en.wikipedia.org/wiki/In-place_algorithm)), and (2) it is a [stable sorting algorithm](http://en.wikipedia.org/wiki/Sorting_algorithm#Stability) in the sense that input data points which have equal values maintain their relative order in the output. Stability [is important](http://homepages.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf) in applications such as databases.
### 3. Selection sort
The
[selection sort](http://en.wikipedia.org/wiki/Selection_sort) algorithm does the following: for each
i from
0 to
n-2, find the smallest element in the suffix
A[i..n-1] and swap that element with
A[i].
/** * ----------------------------------------------------------------------------- * The Seclection Sort algorithm * for each i from 0 to n-2, move the i'th smallest element to its position * ----------------------------------------------------------------------------- */ void selection_sort(vector<int> &vec) { int i, j, k; for (i=0; i<vec.size()-1; i++) { j=i; for (k=i+1; k<vec.size(); k++) if (vec[k] < vec[j]) j=k; if (j!=i) swap(vec[i], vec[j]); } }
Finding the smallest element in
A[i..n-1] takes
n-i-1 steps, which only involves comparisons. Then, one single swap puts the correct element into
A[i]. Hence, the total number of comparisons is
, which is also the order of the run time. The number of data movements is only
. Thus, if we were sorting large objects (instead of integers), we might prefer selection sort over insertion sort, even though both algorithms have worst-case run time
. The sorting is in-place. Selection sort always runs in time
, even when the input is already sorted.
At this point, it should be noted that we do not always have to move the objects, depending on what we want out of sorting. For example, we can sort an array of pointers (or indices) to the objects without moving them explicitly. In that case, we only swap the pointers which is an inexpensive operation. On the other hand, if we seriously want to sort memory blocks according to some criterion, then the moves do matter. If implemented properly, the algorithm can be made stable; but then the number of moves can become
, negating the major advantage of selection sort.
### 4. Merge sort
Both selection sort and insertion sort have
-worst-case running time, which might be too high for many applications. (We will see some data later.)
[Merge sort](http://en.wikipedia.org/wiki/Merge_sort) is a classic [divide and conquer](http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm) algorithm which has a
run time, which is asymptotically optimal among the
[comparison sort algorithms](http://en.wikipedia.org/wiki/Comparison_sort)! Roughly speaking, each comparison reveals one bit of information, and there are
cases to distinguish; thus, there must be at least one case for which
comparisons are necessary. (The approximation
can be derived from
[Stirling approximation](http://mathworld.wolfram.com/StirlingsApproximation.html).)
The idea of merge sort is extremely simple: we split the input array into two halves, recursively sort the left and the right halves, and then
*merge* the two halves. The key step is the merge step when we scan the two (sorted) halves left to right simultaneously and put the smaller element into the merged output. This idea is perhaps best explained in codes:
/** * ----------------------------------------------------------------------------- * merges two halves * ----------------------------------------------------------------------------- */ void merge(vector<int> &target, const vector<int> &left, const vector<int> &right) { if (target.size() != left.size() + right.size()) return; // sanity check size_t i=0, j=0, k=0; while (i < left.size() && j < right.size()) { if (left[i] <= right[j]) // stable, if '<' is used then unstable target[k++] = left[i++]; else target[k++] = right[j++]; } while (i < left.size()) target[k++] = left[i++]; while (j < right.size()) target[k++] = right[j++]; } /** * ----------------------------------------------------------------------------- * The Merge Sort algorithm * - create a copy of the left half, and a copy of the right half * - recursively sort the left half and the right half * - then merge the two halves * ----------------------------------------------------------------------------- */ void merge_sort(vector<int> &vec) { size_t n = vec.size(); if (n <= 1) return; vector<int> left(vec.begin(), vec.begin()+n/2); vector<int> right(vec.begin()+n/2, vec.end()); merge_sort(left); merge_sort(right); merge(vec, left, right); }
For a target array of size
, the merge step takes
-time. Hence, if we let
be the time it takes merge sort to sort a vector of length
, then we have the following recurrence relation:
for some constant
which represents the fact that the merge step takes time
. Now, as we have shown in the Fibonacci and the binary search ananalysis, it is often safe to ignore the issue of integrality; we can rewrite the recurrence as
Every recurrence relation needs a base case. In our case,
. To solve this recurrence, we can draw a tree of depth
, where
is such that
because that is the depth when the base case applies. Each level of the tree contributes
to the total run time. There are
levels. Thus, the worst-case run time for merge sort is
.
The worst-case run time is great! However, merge sort suffers from the space-complexity problem. Consider, for example, an input of size
n=16. First, two subarrays of size
8 each are created. Then, to sort the left subarray two subarrays of size
4 each are created and so on. Once the left side is sorted (after the call to
merge_sort(left)), the extra space used for the left-side sort is released, the function returns, and the same process is repeated for the right side. Hence, if we let
be the total extra space used for merge-sorting an input of size
, we have the following recurrence:
for some constant
, which roughly measures how many bytes each input item requires. We can use the recurrence tree method again: the tree has
levels from
where level
contributes
to the total space complexity. Hence,
In particular, merge sort as implemented above is not an in-place sorting algorithm. It is possible to make merge-sort in place, at the cost of considerable code complexity.
Merge sort as shown above is stable, has
comparisons and
item moves. Thus, merge sort is very predictable, has nice worst-case run time. But, even when the input is already sorted it still takes
time because of all the copying.
### 5. Solving recurrences
So, we have seen several recurrences of the forms
(from binary search,
fib4())
(run time of merge sort)
(extra space complexity of merge sort)
In each of these cases, we can draw a tree and roughly estimate the contribution of each level to the overall function. The recurrence tree is a paticularly quick way of guessing a solution to the recurrence relation. In this course, we will not emphasize the proof part where after guessing we have to inductively prove that our guess works. You will do more formal proofs in CSE 331 and CSE 431. The recurrence tree method can be used to “solve” similar recurrences. Try the following:
### 6. Quicksort
The next sorting algorithm we discuss is
[Quick sort](http://en.wikipedia.org/wiki/Quicksort) by [Tony Hoare](http://en.wikipedia.org/wiki/Tony_Hoare) from 1960. The algorithm is in a sense an opposite of merge sort: merge sort has trivial partitioning and non-trivial merging, while quick sort has non-trivial partitioning and trivial merging. The main idea of quick sort has tree steps. Let
A[p..q] be a sub-array that we want to sort.
- The partition step: first, we rearrange items in
A[p..q]such that there is an index
p ≤ r ≤ qwhere
A[i] < A[r]for all
i = p..r-1and
A[r] ≤ A[i]for all
i=r+1..q.
- Recursively sort
A[p..r-1]
- Recursively sort
A[r+1..q]
Because the left part and the right part are already in the correct order, no merging is necessary.
/** * ----------------------------------------------------------------------------- * The Quick Sort algorithm * - we rearrange the members vec[p...q] so that there will be some r between * p and q such that all vec[i] < vec[r] for p <= i < r and * vec[r] <= vec[j] for r < j <= q * - then sort vec[p..r-1] and vec[r+1..q] * ----------------------------------------------------------------------------- */ void qs_with_range(vector<int> &vec, int p, int q) { if (p >= q) return; // partition int r=p-1; for (int j=p; j<q; j++) if (vec[j] < vec[q]) swap(vec[++r], vec[j]); swap(vec[++r], vec[q]); // sort the left & the right parts qs_with_range(vec, p, r-1); qs_with_range(vec, r+1, q); } /** * ----------------------------------------------------------------------------- * Wrapper to the quick sort algorithm * ----------------------------------------------------------------------------- */ void quick_sort(vector<int> &vec) { qs_with_range(vec, 0, vec.size()-1); }
In the
qs_with_range sub-routine, we use
vec[q] as the
*pivot* element and try to partition
vec[p..q] around that element. The choice of the pivot element is crucial.
First, let’s consider the case when the pivot element roughly partition
vec[p..q] into roughly equal-size halves. Then, because the partition step takes time
, it is not hard to see that the run time recurrence for quick sort is the same as that of merge sort:
which leads to an overall
run time.
Second, if the input is either in sorted order or in the reversed sorted order, then we obtain the recurrence
which (by the recurrence tree method) gives
. We can see this behavior when we experiment with the sorting algorithms below.
Third, suppose we are not too unlucky and we get a
vs
partition each time, then the recurrence is
, which solves to be
again!
The observation leads to the following natural idea: instead of always partitioning around
vec[q] as the pivot, we can pick a random element in
vec[p..q] to be a pivot. Then, with very high probability we have a good partition and the overall run time is
in expectation.
/** * ----------------------------------------------------------------------------- * The Randomized Quick Sort algorithm * - pick a random pivot, that's all * ----------------------------------------------------------------------------- */ void rqs_with_range(vector<int> &vec, int p, int q) { if (p >= q) return; // pick a random pivot int m = rand() % (q-p+1); swap(vec[q], vec[p+m]); // partition int r=p-1; for (int j=p; j<q; j++) if (vec[j] < vec[q]) swap(vec[++r], vec[j]); swap(vec[++r], vec[q]); // sort the left & the right parts rqs_with_range(vec, p, r-1); rqs_with_range(vec, r+1, q); } /** * ----------------------------------------------------------------------------- * Wrapper to the randomized quick sort algorithm * ----------------------------------------------------------------------------- */ void randomized_quick_sort(vector<int> &vec) { srand(static_cast<unsigned int>(time(0))); rqs_with_range(vec, 0, vec.size()-1); }
It can be proved that the expected run-time of randomized quick sort is
, and the run-time is in this order with high probability. In practice, quick sort is usually very fast, even faster than merge sort. This is an example of a
[Las Vegas algorithm](http://en.wikipedia.org/wiki/Las_Vegas_algorithm), which is a randomized algorithm which always gives a correct output but the (worst-case) running time varies. By contrast, a [Monte Carlo](http://en.wikipedia.org/wiki/Monte_Carlo_algorithm) algorithm is a randomized algorithm which has a bounded worst-case run time but the output quality varies.
Even though partitioning is done in place, the recurive calls will require
extra space (the calls are
-level deep). See
[this paper](http://dl.acm.org/citation.cfm?id=359619.359631).
Quick sort can be made
-worst-case run time if we use a linear time algorithm to select the median of
vec[p..q] to partition around.
[The linear time median finding](http://en.wikipedia.org/wiki/Selection_algorithm) algorithm is classic, and you will learn about it in CSE 331 or CSE 431.
### 7. The (Binary) Heap data structure and the heapsort algorithm
A
[(binary) max heap](http://en.wikipedia.org/wiki/Binary_heap) is a data structure which can be visualized as a *complete binary tree*, which is a binary tree in which every level is completely filled except for possibly the last level which is filled from left to right as much as possible. Each node in the (max) heap holds a key; for our purposes in this lecture keys are integers. A parent node has key greater than or equal to the key of each of its children. Hence, the key of the root node is always the maximum key among all nodes. The following is an example max heap.
In a min heap, the parent’s key is at most the children’s keys. And thus the root node has the smallest key. A min heap can be used to implement a
[priority queue](http://en.wikipedia.org/wiki/Priority_queue) which is an extremely useful data structure. In fact, the [Dijkstra’s shortest path algorithm](http://en.wikipedia.org/wiki/Dijkstra's_algorithm) often needs a priority queue; and half the networks on the Internet run a version of Dijkstra’s algorithm every few minutes or so to implement their [link-state routing protocols](http://en.wikipedia.org/wiki/Link-state_routing_protocol). For now, let us get back to the max heap. By heap we mean max heap for the rest of this lecture.
We can implement a heap using an array of keys. If the heap has
n nodes then the array (or vector) has
n elements where the indices of the nodes in the array are numbered from the root down, left to right, starting from
0 as shown in the following picture.
From the picture, it is not hard to see how to compute the index of the parent, the left, or the right child of a given node indexed
i.
Two sub-routines are important in building and using a heap:
heapify(array)turns an arbitrary array into a heap
sink(i, n, array)operates on the node indexed
iof the heap
array[0..n-1]. The procedure assumes that both sub-trees below node
iare already heaps, and “sinks”
idown (while floating some nodes up) until the sub-tree rooted at
iis also a heap. This way, we can perform
heapifyby
sink()‘ing from the bottom up.
Once the two sub-routines are in order, the heap sort algorithm simply builds a heap out of the input array, swap the max element to the end of the array and recursively call
sink(0, n-1, array) to heapify the prefix. All three functions in C++ are self-explanatory.
/** * ----------------------------------------------------------------------------- * sink node i of the heap vec[0..n-1] * - uses a recursive strategy for easy explanation * - if the greater of the left or the right child is greater than the node * then swap and sink that subtree * ----------------------------------------------------------------------------- */ void recursive_sink(vector<int> &vec, size_t i, size_t n) { size_t left = 2*i + 1; if (n > vec.size() || left >= n) return; size_t right = left + 1; // possibly >= n size_t my_pick = (right >= n) ? left : (vec[right] > vec[left]) ? right : left; if (vec[i] < vec[my_pick]) { swap(vec[i], vec[my_pick]); recursive_sink(vec, my_pick, n); } } /** * ----------------------------------------------------------------------------- * turn the input vector into a heap * ----------------------------------------------------------------------------- */ void heapify(vector<int> &vec) { for (int i=vec.size()/2; i>=0; i--) recursive_sink(vec, i, vec.size()); } /** * ----------------------------------------------------------------------------- * The Heap Sort algorithm * - heapify the array of size n * - swap the first and the last * - sink the first and recurse * ----------------------------------------------------------------------------- */ void heap_sort(vector<int> &vec) { heapify(vec); for (int j=vec.size()-1; j>=1; j--) { swap(vec[0], vec[j]); recursive_sink(vec, 0, j); } }
The
recursive_sink() function has
levels of recursive calls, imposing an extra
-space complexity. Staring at the function for a while, it seems possible to turn it into an iterative procedure. (Formally,
recursive_sink() is a form of
[tail recursion](http://en.wikipedia.org/wiki/Tail_call) which can always be turned into an iterative procedure.)
/** * ----------------------------------------------------------------------------- * "un-spinning" the previous recursive sinking procedure, so now the function * is non-recursive and only uses O(1)-extra space, making heap_sort a proper * in place sorting algorithm * ----------------------------------------------------------------------------- */ void sink(vector<int> &vec, size_t i, size_t n) { if (n > vec.size()) return; size_t left, right, my_pick; while ((left = 2*i+1) < n) { right = left + 1; // note: right might be >= n my_pick = right >= n ? left : vec[right] > vec[left] ? right : left; if (vec[i] >= vec[my_pick]) break; // i's subtree is already a heap swap(vec[i], vec[my_pick]); i = my_pick; } }
Then, we simply let
heapify() and
heap_sort() call
sink() instead of
recursive_sink(). Since the height of a complete binary tree with
nodes is
, the
sink(vec, i, n) procedure takes
time. The
heapify() procedure, at first glance, seems to work in time
because there are about
nodes to be
sink()‘ed and each
sink() takes
-time. However, the heights of the nodes to be sinked start from
1 and increase gradually to
. There are at most
nodes at height
. Hence, the total run time for
heapify() is big-O of
Consequently,
heapify() is a linear time algorithm. And,
heap_sort runs in
time in the worst case. This is a rather beautiful result when a really simple data structure conceptually gives rise to an
*in place* sorting algorithm. Unfortunately it is not stable.
### 8. Experimenting and evaluating the sorting algorithms
I wrote some codes to experiment with all five of the above algorithms. You should be able to fill in the
search_sort.cpp and
search_sort.h files by simple cut and pasting.
/* ****************************************************************************** * file name : main.cpp * author : Hung Q. Ngo * description: test run all of the following sorting algorithms * - insertion sort * - selection sort * - merge sort * - quick sort * - randomized quick sort * - heap sort * on random, sorted, and inversedly sorted inputs of varying sizes * print the run times out in a csv file to be opened with Excel * I did the graphing from Excel ****************************************************************************** */ #include <iostream> #include <vector> #include <cstdlib> // for rand() and srand() #include <ctime> // for time() #include "search_sort.h" using namespace std; void print_vec(vector<int>& vec); /** * ----------------------------------------------------------------------------- * print a vector of integers, finish with a new line * ----------------------------------------------------------------------------- */ void print_vec(vector<int>& vec) { for (int i=0; i<vec.size(); i++) { cout << vec[i] << " "; } cout << endl; } /** * ----------------------------------------------------------------------------- * returns a random vector of n elements, each from 0 to n-1 * not efficient due to vector copying, but should not affect runtime much * ----------------------------------------------------------------------------- */ vector<int> random_vector(size_t n) { srand(static_cast<unsigned int>(time(0))); vector<int> ret(n); for (int i=0; i<n; i++) ret[i] = rand() % n; return ret; } /** * ----------------------------------------------------------------------------- * returns a descending vector of n elements, from n down to 1 * ----------------------------------------------------------------------------- */ vector<int> descending_vector(size_t n) { vector<int> ret(n); for (int i=0; i<n; i++) ret[i] = n-i-1; return ret; } /** * ----------------------------------------------------------------------------- * returns a ascending vector of n elements * ----------------------------------------------------------------------------- */ vector<int> ascending_vector(size_t n) { vector<int> ret(n); for (int i=0; i<n; i++) ret[i] = i; return ret; } /** * ----------------------------------------------------------------------------- * returns an almost sorted array, only some 10 of the pairs are swapped * ----------------------------------------------------------------------------- */ vector<int> almost_ascending_vector(size_t n) { vector<int> ret(n); int i, j,k; srand(static_cast<unsigned int>(time(0))); for (i=0; i<n; i++) ret[i] = i; for (i=0; i<10; i++) { j = rand() % n; k = rand() % n; swap(ret[j], ret[k]); } return ret; } /** * * ----------------------------------------------------------------------------- * run a sorting algorithm pointed to by sort_algo * the test data is obtained by get_data * the different sizes of the test data is stored in input_sizes * ----------------------------------------------------------------------------- */ void test_run(vector<int> input_sizes, void (*sort_algo)(vector<int>&), vector<int> (*get_data)(size_t)) { time_t start,end; double dif; vector<int> data; for(int i=0; i<input_sizes.size(); i++) { time(&start); data = get_data(input_sizes[i]); sort_algo(data); time (&end); dif = difftime(end,start); cout << dif; if (i < input_sizes.size()-1) cout << ","; else cout << endl; } } /** * ----------------------------------------------------------------------------- * I'm a bit lazy here, could use a map to clean the code up * ----------------------------------------------------------------------------- */ void gather_data(vector<int> input_sizes, vector<int> (*fp)(size_t)) { cout << "Insertion,"; test_run(input_sizes, insertion_sort, fp); cout << "Selection,"; test_run(input_sizes, selection_sort, fp); cout << "Merge,"; test_run(input_sizes, merge_sort, fp); cout << "Heap,"; test_run(input_sizes, heap_sort, fp); cout << "Quicksort,"; test_run(input_sizes, quick_sort, fp); cout << "Randomized Quicksort,"; test_run(input_sizes, randomized_quick_sort, fp); } /** * ----------------------------------------------------------------------------- * Test those guys and gather some data * We have 4 sorting algorithms: Insertion, Selection, Merge, Quick, and RQuick * We'll test them with different sizes and different types of input: * n = 1000, 2000, 10000, 20000, 50000, 100000 * input already sorted * input inversedly sorted * input randomized * input almost sorted * n=200000 gives me segmentation fault * ----------------------------------------------------------------------------- */ int main() { // to test a specific sorting algorithm you can do /* vector<int> vec = almost_ascending_vector(20); cout << "Before: "; print_vec(vec); heap_sort(vec); cout << "After: "; print_vec(vec); */ static int arr[] = {1000,2000,10000,20000,50000,100000}; vector<int> input_sizes(arr, arr + sizeof(arr)/sizeof(int)); cout << "Randomized input: " << endl; for (int i=0; i<input_sizes.size(); i++) cout << "," << input_sizes[i]; cout << endl; gather_data(input_sizes, random_vector); cout << endl; cout << "Almost sorted input: " << endl; for (int i=0; i<input_sizes.size(); i++) cout << "," << input_sizes[i]; cout << endl; gather_data(input_sizes, almost_ascending_vector); cout << endl; cout << "Sorted input: " << endl; for (int i=0; i<input_sizes.size(); i++) cout << "," << input_sizes[i]; cout << endl; gather_data(input_sizes, ascending_vector); cout << endl; cout << "Inversedly sorted input: " << endl; for (int i=0; i<input_sizes.size(); i++) cout << "," << input_sizes[i]; cout << endl; gather_data(input_sizes, descending_vector); }
The following graphs give the run times for different algorithms under different inputs. I tried input sizes of 200K but some algorithm didn’t finish due to memory errors. I didn’t bother to check which one did not finish. But that’s from my laptop. I will probably try again on
timberlake or my
imac which is much more powerful.
For randomized inputs, selection sort is way worse than insertion, which starts to get worse than the
algorithms at around 10K input size. Quick sort, Merge sort, and Randomized Quick sort all work very well. Heap sort is a little bit slower at n = 100K, but it is still under 1 second. Since the input is randomized, we theoretically expected that there is no difference between quick sort and randomized quick sort, and that shows. (I should have run more experiments and average out to be experimentally sound; but I’m lazy. You can do that youself.)
For inversely sorted input, quick sort starts to show its true color of a
algorithm. It is still a lot faster than selection sort though. In this case, insertion sort and quick sort are comparable at n = 100K: they take more than 130 seconds.
The same problem with quick sort shows up when the input is already sorted. In this case, insertion sort is superb. It is a linear time algorithm for this input, after all.
For almost sorted inputs, again insertion sort does very well! (You should be able to see why that is the case.)
### 9. Sorting generic objects
#### 9.1. C++ Template functions
So far we are only able to sort integers. To sort doubles or strings, what we can do is to overload those functions by cut-and-pasting the codes and change the types from
int to
double and to
string. This strategy does not scale, obviously.
[C++ function templates](http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Ffunction_templates.htm) is a construct which allows for [generic programming](http://en.wikipedia.org/wiki/Generic_programming) in which the data types are essentially the parameters to the functions. Briefly, instead of sorting
int or
double, we can write a sorting function which sorts an
Item_Type (which is just a place-holder name) which will be replaced by a specific type later when we invoke the function. We have seen templates before, in the forms
vector<int> or
vector<string>. What that says is that
vector is a template class, which can be a vector of strings or a vector of integers. When we explicitly write
vector<string> the compiler replaces the
Item_Type place holder in the
vector template class definition with the specific type
string.
For a template function, it is very simple syntactically
/* ****************************************************************************** * file name : templ_sort.h * author : Hung Q. Ngo * description: implementation a template version of randomized quick sort * and insertion sort ****************************************************************************** */ #include <vector> #include <cstdlib> // for rand() and srand() #include <ctime> // for time() /** * ----------------------------------------------------------------------------- * Template Insertion Sort * for each i from 1 to n-1, insert vec[i] to the right place in the prefix * ----------------------------------------------------------------------------- */ template <typename Item_Type> void insertion_sort(std::vector<Item_Type> &vec) { Item_Type temp, j; for (int i=1; i<vec.size(); i++) { temp = vec[i]; j = i-1; // assumes compiler knows how to do '>' with Item_Type while (j >= 0 && vec[j] > temp) { vec[j+1] = vec[j]; j--; } vec[j+1] = temp; } } /** * ----------------------------------------------------------------------------- * The Randomized Quick Sort algorithm * - pick a random pivot, that's all * ----------------------------------------------------------------------------- */ template <typename Item_Type> void rqs_with_range(std::vector<Item_Type> &vec, int p, int q) { if (p >= q) return; // pick a random pivot int m = std::rand() % (q-p+1); std::swap(vec[q], vec[p+m]); // partition int r=p-1; for (int j=p; j<q; j++) if (vec[j] < vec[q]) std::swap(vec[++r], vec[j]); std::swap(vec[++r], vec[q]); // sort the left & the right parts rqs_with_range(vec, p, r-1); rqs_with_range(vec, r+1, q); } /** * ----------------------------------------------------------------------------- * Wrapper to the randomized quick sort algorithm * ----------------------------------------------------------------------------- */ template <typename Item_Type> void randomized_quick_sort(std::vector<Item_Type> &vec) { std::srand(static_cast<unsigned int>(std::time(0))); rqs_with_range(vec, 0, vec.size()-1); }
The keyword
typename can also be replaced by
class. See
[here](http://blogs.msdn.com/b/slippman/archive/2004/08/11/212768.aspx) for more details.
Note that I’ve put the functions’ implementations in the header file because separate compilation is not possible with template functions: the compiler needs to know the specific type we want before it can generate machine codes. Hence, the easiest solution is to put all the definitions in the header file. There are
[other options](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) too, but for us putting the function template definitions in the header is sufficient.
To use the function templates, you can use the syntax
insertion_sort<double>(vec) as you did
vector<double>, but that is not necessary because if we defined
vector<double> vec then the compiler already knows the type of the vector passed in. Hence, it is sufficient to do the following:
/* ****************************************************************************** * file name : driver.cpp * author : Hung Q. Ngo * description: test a few template sorting algorithms ****************************************************************************** */ #include <iostream> #include <vector> #include "templ_sort.h" using namespace std; /** * ----------------------------------------------------------------------------- * print a vector of Item_Type, finish with a new line * assumes compiler knows how to cout << Item_Type * ----------------------------------------------------------------------------- */ template <typename Item_Type> void print_vec(vector<Item_Type>& vec) { for (int i=0; i<vec.size(); i++) { cout << vec[i] << " "; } cout << endl; } /** * ----------------------------------------------------------------------------- * test template insertion sort * test template quick sort * ----------------------------------------------------------------------------- */ int main() { vector<double> vec; vec.push_back(1.5); vec.push_back(-2.5); vec.push_back(5.3); vec.push_back(-2); vec.push_back(4); cout << "Before: "; print_vec(vec); randomized_quick_sort(vec); cout << "After: "; print_vec(vec); }
The above strategy doesn’t work if we want to sort objects which do not have built-in comparison operators. We can, however, use a
[callback function](http://en.wikipedia.org/wiki/Callback_(computer_programming)) to make our sorting routines almost completely general.
/* ****************************************************************************** * file name : cb_sort.h * author : Hung Q. Ngo * description: implementations of template versions of randomized quick sort * and insertion sort with a callback function ****************************************************************************** */ #include <vector> #include <cstdlib> // for rand() and srand() #include <ctime> // for time() /** * ----------------------------------------------------------------------------- * -1 if a < b, 0 if a==b, 1 if a>b * ----------------------------------------------------------------------------- */ template <typename Item_Type> int default_cmp(Item_Type a, Item_Type b) { return a < b? -1 : a == b ? 0 : 1; } /** * ----------------------------------------------------------------------------- * Template Insertion Sort * for each i from 1 to n-1, insert vec[i] to the right place in the prefix * ----------------------------------------------------------------------------- */ template <typename Item_Type> void insertion_sort(std::vector<Item_Type> &vec, int (*cmp)(Item_Type, Item_Type) = default_cmp) { Item_Type temp; int j; for (int i=1; i<vec.size(); i++) { temp = vec[i]; j = i-1; // assumes compiler knows how to do '>' with Item_Type while (j >= 0 && cmp(vec[j],temp) > 0) { vec[j+1] = vec[j]; j--; } vec[j+1] = temp; } } /** * ----------------------------------------------------------------------------- * The Randomized Quick Sort algorithm * - pick a random pivot, that's all * ----------------------------------------------------------------------------- */ template <typename Item_Type> void rqs_with_range(std::vector<Item_Type> &vec, int p, int q, int (*cmp)(Item_Type, Item_Type)) { if (p >= q) return; // pick a random pivot int m = std::rand() % (q-p+1); std::swap(vec[q], vec[p+m]); // partition int r=p-1; for (int j=p; j<q; j++) if (cmp(vec[j],vec[q])<0) std::swap(vec[++r], vec[j]); std::swap(vec[++r], vec[q]); // sort the left & the right parts rqs_with_range(vec, p, r-1, cmp); rqs_with_range(vec, r+1, q, cmp); } /** * ----------------------------------------------------------------------------- * Wrapper to the randomized quick sort algorithm * ----------------------------------------------------------------------------- */ template <typename Item_Type> void randomized_quick_sort(std::vector<Item_Type> &vec, int (*cmp)(Item_Type, Item_Type) = default_cmp) { std::srand(static_cast<unsigned int>(std::time(0))); rqs_with_range(vec, 0, vec.size()-1, cmp); }
And here’s how to use the above routines
/* ****************************************************************************** * file name : driver.cpp * author : Hung Q. Ngo * description: test a few template sorting algorithms ****************************************************************************** */ #include <iostream> #include <vector> #include <cstdlib> // for rand() and srand() #include <ctime> // for time() // #include "templ_sort.h" #include "cb_sort.h" using namespace std; /** * ----------------------------------------------------------------------------- * print a vector of Item_Type, finish with a new line * assumes compiler knows how to cout << Item_Type * ----------------------------------------------------------------------------- */ template <typename Item_Type> void print_vec(vector<Item_Type>& vec) { for (int i=0; i<vec.size(); i++) { cout << vec[i] << " "; } cout << endl; } int reverse_cmp(double a, double b) { return a>b ? -1 : (a<b) ? 1 : 0; } int str_cmp(string a, string b) { return a.compare(b); } /** * ----------------------------------------------------------------------------- * test template insertion sort * test template quick sort * ----------------------------------------------------------------------------- */ int main() { // sorting doubles, using default comparison operators vector<double> vec; vec.push_back(1.5); vec.push_back(-2.5); vec.push_back(5.3); vec.push_back(-2); vec.push_back(4); cout << "Sorting doubles in increasing order" << endl; cout << "Before: "; print_vec(vec); randomized_quick_sort(vec); cout << "After: "; print_vec(vec); // sorting doubles in reversed order cout << "Sorting doubles in decreasing order" << endl; cout << "Before: "; print_vec(vec); insertion_sort(vec, reverse_cmp); cout << "After: "; print_vec(vec); // sorting strings alphabetically vector<string> str_vec(6); str_vec[0] = "Alex"; str_vec[1] = "Carol"; str_vec[2] = "George"; str_vec[3] = "Charles"; str_vec[4] = "Alice"; str_vec[5] = "Knuth"; cout << "Sorting strings alphabetically" << endl; cout << "Before: "; print_vec(str_vec); insertion_sort(str_vec, str_cmp); cout << "After: "; print_vec(str_vec); }
### 10. A final twist to randomized quick sort
It turns out that the above implementation of randomized quick sort does not work well if the input items are chosen from a few values. In the worst case, for example, if all items in the input array are equal, then the randomized quick sort implementation above will run in
-time. The reason is that in the current implementation all elements strictly less than the pivot are on the left partition, and all elements greater than or equal to the pivot are on the right. Hence, if all input elements are equal then the left part of the partition will be empty and the right part has
n-1 elements. You can use 3-way-partition quicksort which has been
[well-analyzed](http://www.sorting-algorithms.com/static/QuicksortIsOptimal.pdf); but that involves heavy modification of the code.
There is a very simple modification which can take care of this problem. We can allow elements equal to the pivot to be on the left part too. And, we do this randomly: when we are scanning an element which is equal to the pivot, we flip a coin and put it on the left with probability half.
/* ****************************************************************************** * file name : better_rqs.cpp * author : Hung Q. Ngo * description: a minor twist to the randomized quick sort algorithm which * makes it run faster on inputs where the item values belong * to a small finite class ****************************************************************************** */ #include <iostream> #include <vector> #include <cstdlib> // for rand() and srand() #include <ctime> // for time() using namespace std; /** * * ----------------------------------------------------------------------------- * print a vector of Item_Type, finish with a new line * assumes compiler knows how to cout << Item_Type * * ----------------------------------------------------------------------------- */ template <typename Item_Type> void print_vec(vector<Item_Type>& vec) { for (int i=0; i<vec.size(); i++) { cout << vec[i] << " "; } cout << endl; } /** * ----------------------------------------------------------------------------- * -1 if a < b, 0 if a==b, 1 if a>b * ----------------------------------------------------------------------------- */ template <typename Item_Type> int default_cmp(Item_Type a, Item_Type b) { return a < b? -1 : a == b ? 0 : 1; } /** * ----------------------------------------------------------------------------- * The Randomized Quick Sort algorithm * - pick a random pivot, that's all * ----------------------------------------------------------------------------- */ template <typename Item_Type> void rqs_with_range(std::vector<Item_Type> &vec, int p, int q, int (*cmp)(Item_Type, Item_Type)) { if (p >= q) return; // pick a random pivot int m = std::rand() % (q-p+1); std::swap(vec[q], vec[p+m]); // partition int r=p-1; for (int j=p; j<q; j++) { if (rand() % 2 == 0) { if (cmp(vec[j],vec[q])<0) std::swap(vec[++r], vec[j]); } else { if (cmp(vec[j],vec[q])<=0) std::swap(vec[++r], vec[j]); } } std::swap(vec[++r], vec[q]); // sort the left & the right parts rqs_with_range(vec, p, r-1, cmp); rqs_with_range(vec, r+1, q, cmp); } /** * ----------------------------------------------------------------------------- * Wrapper to the randomized quick sort algorithm * ----------------------------------------------------------------------------- */ template <typename Item_Type> void randomized_quick_sort(std::vector<Item_Type> &vec, int (*cmp)(Item_Type, Item_Type) = default_cmp) { std::srand(static_cast<unsigned int>(std::time(0))); rqs_with_range(vec, 0, vec.size()-1, cmp); } /** * ----------------------------------------------------------------------------- * returns a random vector of n elements, each from 0 to k-1 * ----------------------------------------------------------------------------- */ vector<int> random_vector(size_t n, size_t k) { srand(static_cast<unsigned int>(time(0))); vector<int> ret(n); for (int i=0; i<n; i++) ret[i] = rand() % k; return ret; } // ***************************************************************************** int main() { // to test a specific sorting algorithm you can do vector<int> vec = random_vector(50000, 2); cout << "Before: "; print_vec(vec); randomized_quick_sort(vec); cout << "After: "; print_vec(vec); }
## 16 Comments
Anh Hưng soạn cẩn thận ghê, nhưng bài giảng nào cũng soạn thế này chắc hết thời gian nghiên cứu quá.
Có cách nào để tính công giảng bài vào CV không nhỉ, chứ như hiện nay thì có vẻ ông lười cũng giống ông chăm.
![ :D](http://www.procul.org/blog/wp-includes/images/smilies/icon_biggrin.gif)
Hi Nam, làm kỹ thì lần sau dạy lại đỡ tốn thời gian hơn nhiều. Ngoài ra, với những môn học thú vị và quan trọng như data structures, viết bài giảng cẩn thận cũng rất thú. Khi chạy các thí nghiệm ta thường khám phá ra những quan sát đơn giản mà phân tích lý thuyết có thể bỏ sót. Vả lại, không chạy thì làm thế nào mà biết merge sort, randomized quick sort, và heap sort cái nào thật sự nhanh hơn trên thực tế?
Thật ra tôi thấy những GS nổi tiếng thường có các bài giảng rất hay, chi tiết, và chắc chắn là họ không cảm thấy mất thì giờ. (Hoàn toàn không có ý nói là tôi là một trong số họ, nhưng đó là điều tôi thấy nên học từ họ.) Việc trình bày lại một đề tài cơ bản như cấu trúc dữ liệu cũng là một công việc cực kỳ thú vị. Tôi thật sự không thích mấy cuốn sách hiện nay, kể cả textbook tôi dùng cho lớp này. Textbook mà viết sai thuật toán tìm kiếm nhị phân, chán phèo.
Em cũng nghĩ là viết ra chi tiết, kể cả những thứ rất cơ bản sẽ giúp mình có một cái nhìn tốt hơn (và chính xác hơn) về vấn đề đó. Ngoài ra thì đây cũng là một cách khắc phục bệnh “ngại” nữa.
![ :)](http://www.procul.org/blog/wp-includes/images/smilies/icon_smile.gif)
Anh Hưng có dạy thuật toán tìm kiếm Grover trên máy tính lượng tử không ạ? Một ví dụ đẹp và đơn giản cho thấy sức mạnh của máy lượng tử… (độ phức tạp N^{1/2} vượt qua cận dưới là thời gian tuyến tính cho máy tính thông thường)
Hi RongChoi, Chắc là không. Lớp này là lớp CTDL chứ không phải lớp thuật toán.
Bai giang cua thay Hung chi tiet ky luong ghe. Em cung vua hoc lop Data Structure vao semester truoc, nhung giao su cua em ko chuan bi bai giang ky luong nhu the nay.
Chào GS Hưng, GS cho em hỏi là với các data 2 chiều (điểm trên bản đồ, gồm kinh độ và vĩ độ) thì có chiến lược nào để sắp xếp và tìm kiếm tốt nhất không ạ. Số là em có một bản đồ với khoảng 35000 điểm, và phải hiển thị dưới board nhúng, không thể load tất cả vào ram được. Cho nên em muốn sort trước trên PC rồi mới đưa xuống board, khổ nỗi em không biết cách so sánh cho loại data này như thế nào, mong anh cho em vài gợi ý. Em cám ơn
![ :D](http://www.procul.org/blog/wp-includes/images/smilies/icon_biggrin.gif)
@it4rb, không rõ bạn muốn tìm kiếm như thế nào. Ví dụ, bạn có thể đinh nghĩa phép so sánh
rồi dùng tìm kiếm nhị phân như trên.
Cám ơn GS.
Em cần tìm kiếm các điểm nằm trong hình chữ nhật cho trước. Em sẽ xem lại theo cách của GS.
@it4rb:
Bài toán của bạn giống trường hợp đặc biệt của một bài toán tìm kiếm với range queries trong database. Ví dụ, trong DB ta có thể có một relation gồm 2 cột họ và tên. Và, ta muốn tìm tất cả các cặp (họ, tên) thuộc ([A–N], [X–Z]) chẳng hạn. Các range queries có thể gồm nhiều chiều hơn, ví dụ tìm một hộp trong không gian 3 chiều.
K-d Tree và R tree là các cấu cúc dữ liệu cổ điển cho bài toán đó.
Trong code về binary search, nên chăng cứ để: mid = (left+right)/2 -> vì nó đúng với bản chất vấn đề hơn, và thêm bình luận là nên lập công thức mid = left + (right – left)/2; để tránh tràn số. => những chi tiết kĩ thuật cũng quan trọng nhưng có lẽ không quan trọng bằng ý tưởng của thuật toán. Tương tự như vậy trong Insertion sort, có thể sử dụng luôn method insert của vector?
@Vo Danh:
Dùng insert của vector là sai vấn đề vì nó che thời gian chạy, và thậm chi nó … chạy sai vì nó sẽ shift tất cả các phần tử về bên phải
Tôi không thấy (l+r)/2 là “đúng bản chất vấn đề hơn”.
http://www.sorting-algorithms.com/
Bài giảng của bác thật tuyệt vời
Em đóng góp với bác trang này có animation về các thuật toán sắp xếp với các trạng thái ban đầu khác nhau, mà em nghĩ là nếu bố sung vào bài giảng được thì cũng rất thú vị. Hồi trước em học về sorting algorithm xem cái này nó visualize, ngộ ra bằng mấy chỉ đọc pseudo code
![ :D](http://www.procul.org/blog/wp-includes/images/smilies/icon_biggrin.gif)
Cảm ơn Nam. Tôi cũng biết website đó. Trong bài có câu: “This website has nice annimations of the sorting algorithms we discuss here.” và trong câu có link đến website Nam dẫn
![ :-)](http://www.procul.org/blog/wp-includes/images/smilies/icon_smile.gif)
Có hình rồi thì thêm tiếng nữa mới thú vị bác Hưng à, http://www.youtube.com/watch?v=t8g-iYGHpEA – What different sorting algorithms sound like
![ :D](http://www.procul.org/blog/wp-includes/images/smilies/icon_biggrin.gif)
@tpd: cảm ơn! Còn đây là cả hình lẫn tiếng http://www.youtube.com/watch?v=ywWBy6J5gz8

Server: Apache


markdown:
-
[Thông báo kết quả tuyển sinh đại học vừa làm vừa học năm 2014 (31/10/2014)](/vn/thong-tin/76/1840_thong-bao-ket-qua-tuyen-sinh-dai-hoc-vua-lam-vua-hoc-nam-2014-31-10-2014.html)
-
[Thông báo mở lớp bổ sung kiến thức cho thí sinh dự thi tuyển sinh trình độ thạc sĩ năm 2015 (22/10/2014)](/vn/thong-tin/76/1832_thong-bao-mo-lop-bo-sung-kien-thuc-cho-thi-sinh-du-thi-tuyen-sinh-trinh-do-thac-si-nam-2015-22-10-2014.html)
-
[Thông báo gia hạn thời gian nhận hồ sơ tuyển sinh đại học vừa làm vừa học năm 2014 (02/10/2014)](/vn/thong-tin/76/1826_thong-bao-gia-han-thoi-gian-nhan-ho-so-tuyen-sinh-dai-hoc-vua-lam-vua-hoc-nam-2014-02-10-2014.html)
-
[Thông báo xét tuyển NV2 (đợt 2) và tiếp nhận xét tuyển NV2 (đợt 3) ngành Công nghệ điện ảnh – truyền hình (01/10/2014)](/vn/thong-tin/76/1825_thong-bao-xet-tuyen-nv2-dot-2-va-tiep-nhan-xet-tuyen-nv2-dot-3-nganh-cong-nghe-dien-anh-truyen-hinh-01-10-2014.html)
-
[Thông báo về việc xin ý kiến vào Dự thảo “Đề án Tuyển sinh đại học, cao đẳng chính quy của Trường ĐH SK-ĐA HN” (16/09/2014)](/vn/thong-tin/76/1812_thong-bao-ve-viec-xin-y-kien-vao-du-thao-de-an-tuyen-sinh-dai-hoc-cao-dang-chinh-quy-cua-truong-dh-sk-da-hn-16-09-2014.html)
-
[Thông báo xét tuyển trình độ tiến sĩ năm 2014 (30/08/2014)](/vn/thong-tin/76/1806_thong-bao-xet-tuyen-trinh-do-tien-si-nam-2014-30-08-2014.html)
-
[Thông báo kết quả xét tuyển Khối A - NV1, NV2 đợt 1 và chỉ tiêu xét tuyển NV2 đợt 2 (28/09/2014)](/vn/thong-tin/76/1805_thong-bao-ket-qua-xet-tuyen-khoi-a-nv1-nv2-dot-1-va-chi-tieu-xet-tuyen-nv2-dot-2-28-09-2014.html)
-
[Khai giảng khoa học dựng phim và âm thanh](/vn/thong-tin/77/1848_khai-giang-khoa-hoc-dung-phim-va-am-thanh.html)
-
[Hiệu trưởng Trường Điện ảnh Sydney sang thăm và làm việc](/vn/thong-tin/77/1847_hieu-truong-truong-dien-anh-sydney-sang-tham-va-lam-viec.html)
-
[Đoàn đại biểu Quỹ Giao lưu Quốc tế Nhật Bản sang thăm và làm việc tại trường](/vn/thong-tin/77/1838_doan-dai-bieu-quy-giao-luu-quoc-te-nhat-ban-sang-tham-va-lam-viec-tai-truong.html)
-
[Chuyên gia Đức giảng dạy lớp bồi dưỡng và nâng cao nghiệp vụ đạo diễn phim truyện](/vn/thong-tin/77/1824_chuyen-gia-duc-giang-day-lop-boi-duong-va-nang-cao-nghiep-vu-dao-dien-phim-truyen.html)
-
[Đoàn đại biểu Trường ĐH Bangkok (Thái Lan) sang thăm và làm việc cùng Ban Giám hiệu Trường ĐH Sân khấu - Điện ảnh Hà Nội (24/04/2014)](/vn/thong-tin/77/1636_doan-dai-bieu-truong-dh-bangkok-thai-lan-sang-tham-va-lam-viec-cung-ban-giam-hieu-truong-dh-san-khau-dien-anh-ha-noi-24-04-2014.html)

WARC-Type: response

Content-Type: application/http; msgtype=response

WARC-Truncated: length

P3P: policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"

X-Powered-CMS: Bitrix Site Manager (b7d744bd4c4c12c2fdeabc8fd9439c2d)

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Pragma: no-cache

Content-Encoding: x-gzip

Connection: close

Content-Type: text/html; charset=UTF-8


markdown:
Trước đó, như Thanh Niên đã thông tin, khoảng 1 giờ 30 phút sáng 29.12, có hai người đàn ông đi trên một chiếc xe tay ga tới phố Vũ Kiệt thuộc P.Tiền An, TP.Bắc Ninh. Sau khi xe dừng, hai người đàn ông này mở cốp lục tìm một vật gì đó thì một tiếng nổ lớn vang lên, nhiều cửa kính, cửa gỗ của những ngôi nhà gần đó bị hư hỏng nặng, thi thể hai người đàn ông bị xé thành nhiều mảnh, văng xa tới vài chục mét. Công an tỉnh Bắc Ninh xác định họ là Đỗ Văn Mười (38 tuổi, sinh sống tại khu chợ Nhớn thuộc P.Tiền An, TP.Bắc Ninh, Bắc Ninh) và Nguyễn Văn Hải (46 tuổi, quê quán ở TX.Chí Linh, Hải Dương).
Có mặt tại hiện trường, nhiều người dân sinh sống tại P.Tiền An cũng như TP.Bắc Ninh cho biết Đỗ Văn Mười sống bằng nghề tín dụng đen và đòi nợ thuê. Khi anh này xuất hiện ở đâu thì chắc chắn ở đó ắt sẽ có chuyện. Trước khi xảy ra vụ nổ mìn, người nhà của Mười đã có mâu thuẫn với một thành viên trong gia đình sinh sống ngay trên phố Vũ Kiệt. “Khả năng hai người này ôm mìn tự chế để đi ném vào nhà người ta. Nhưng trong lúc đang đấu dây thì phát nổ đấy thôi”, một người dân sinh sống ở khu vực chợ Nhớn (Bắc Ninh) nói. Cũng theo người này, ngôi nhà mà hai nạn nhân định ốp mìn chỉ cách nơi xảy ra vụ nổ một quãng đường ngắn.
Tới trưa 29.12, gia đình nạn nhân tới hiện trường xin nhận phần thi thể tìm được về mai táng. Khi biết phóng viên có ý định tìm tới khu vực chợ Nhớn (nơi gia đình Mười sống) để tìm hiểu thêm nhân thân của Mười, nhiều người dân tại hiện trường vụ nổ tỏ ý e ngại và khuyên can. Theo họ, ở TP.Bắc Ninh chẳng ai muốn gây chuyện với Mười. “Đám “trẻ con” - cách người dân gọi những thanh niên đang tập tọe bước vào giới giang hồ - thoáng nghe tên người này đã phải run sợ”, một người dân nói.
Tới cuối giờ chiều qua, các gia đình sinh sống trên phố Vũ Kiệt đã thu dọn những gì còn lại của vụ nổ mìn. Do sức công phá lớn của vụ nổ mìn nên các hộ này đều phải kỳ công dùng xà phòng để chà đánh, sau đó dùng máy bơm nước phụt lên những mảng tường bám đầy máu. Nhiều mảnh nhỏ thi thể của hai người đàn ông còn sót lại trên những cành cây, nên một số hộ phải cho chặt cây, vứt bỏ những chậu cảnh bên hiên nhà.
Hiện trường vụ nổ mìn kinh hoàng - Ảnh: Minh Sang
Người dân lau rửa các vết máu bám trên tường nhà
Hà An
>> Nổ mìn ở Bắc Ninh, 2 người chết
Tin tức Thanh Niên Online
Tin sao iHay
Tin nóng
Tin thể thao
Sài Gòn Ẩm Thực
World Cup 2014
Tổng biên tập: NGUYỄN QUANG THÔNG
Phó tổng biên tập phụ trách Thanh Niên Online: HẢI THÀNH
Phụ trách tòa soạn Thanh Niên Online:
- Ủy viên Ban biên tập - Tổng Thư ký tòa soạn: TRẦN VIỆT HƯNG
- Ủy viên Ban biên tập - Phó tổng Thư ký tòa soạn: ĐÀO HỒNG HẠNH
- Phó tổng Thư ký tòa soạn: ĐỖ HÙNG
- Thư ký tòa soạn: NGUYỄN MINH GIAO - NGUYỄN ĐÌNH HUÂN
NGUYỄN XUÂN TOÀN - NGUYỄN TRẦN DUY
Giấy phép xuất bản số 298/GP - BTTTT cấp ngày 29.7.2013
© 2003-2013 Bản quyền thuộc về Báo Thanh Niên
Cấm sao chép dưới mọi hình thức nếu không có sự chấp thuận bằng văn bản
Hotline: Quảng cáo, PR - 0908 78 0404
Thanh Niên Online chạy tốt nhất trên các trình duyệt
Internet Explorer 8.0 trở lên
Firefox 6.0 trở lên
Chrome 14.0 trở lên

X-MS-InvokeApp: 1; RequireReadOnly

Content-Type: text/html; charset=utf-8

Content-Encoding: gzip

Cache-Control: public, s-maxage=600, max-age=600

Vary: Accept-Encoding


markdown:
# Những “siêu cây cảnh” triệu đôĐăng lúc: Thứ ba - 11/10/2011 22:20 - Người đăng bài viết:
[Bahoang](#) **Vì sao cây cảnh có giá triệu đô?**
Theo giới sành chơi
[cây cảnh nghệ thuật](http://www.thegioicayxanh.com/cay-canh/Cay-canh-nghe-thuat/), để một **cây cảnh**đắt giá bạc tỷ cần có những yếu tố sau: Thứ nhất, cây phải có tuổi và phải ngồi trên chậu hàng trăm năm. Thứ hai, cây phải thuộc kỳ hoa dị thảo, kiểu dáng cổ quái, không giống bất cứ cây nào. Thứ ba, cây phải biểu đạt được chủ đề thông qua thế cây. Thứ tư, cây đó phải hợp gu với người chơi, hợp tuổi, sở thích… [cây cảnh](http://www.thegioicayxanh.com/)đạt tiêu chí này không phải dễ. **Một cây cảnh**vài trăm năm tuổi phải được chăm sóc, tỉa tót qua nhiều đời mới đạt thành quả. Như vậy, cây cảnh đó không những đã ăn vào tâm thức người sở hữu mà nó còn trở thành báu vật gia truyền. Vì thế, về mặt tâm linh, không thể định giá được những cây này. Chẳng hạn, cây sanh dáng “long mẫu tử”, tuổi 300 năm, của dòng họ Đỗ ở Nam Điền, Nam Định được định giá lên đến 3 tỷ đồng, nhưng cả dòng họ này nhất quyết không bán. Theo họ, cái giá 3 tỷ đồng cho công phu tuyệt tác trường tồn những 300 năm có lẽ vẫn còn quá rẻ. **cây cảnh**có tuổi vài trăm năm chỉ đếm được trên đầu ngón tay. Chính vì nó lâu năm, nó thành vật gia truyền nên việc mua được nó không phải dễ dàng. Ngay như dại gia Thành “đất” đã gặp một dòng họ ở Ninh Hiệp cả trăm lần rồi, trả giá cũng đến tỷ nọ tỷ kia, nhưng vẫn chưa mua được, bởi nó là “tài sản tâm linh” của cả dòng họ. **cây cảnh nghệ thuật**thì người Hà Nội sành chơi, chơi tinh túy nhất và cách tạo tác cũng rất riêng biệt, không giống bất cứ nơi nào trong nước, thậm chí khác biệt hoàn toàn với thế giới. ![ Cây cảnh](/uploads/news/2011_10/cay-canh18809-2.jpg)
Các đại gia sành chơi cây đắt tiền đều thổi ý nghĩa tâm linh vào cây. Đại gia Đinh Hồng Quân bỏ ra 2,4 tỷ đồng để mua thêm một cây sanh nữa đặt bên cây sanh 2 tỷ đồng cho chúng có đôi, kẻo xui xẻo. Nguyễn Trọng Thành thì khẳng định, chính cây sung già giữa vườn đã mang lại đại lộc cho anh. Người ta chăm sóc cây sung cả trăm năm trời không có quả, tưởng sung đực, nhưng khi bán cho anh, chỉ vài năm sau nó ra quả chĩu chịt, dù sống cằn cỗi trong chậu, bám vào tảng đá, chỉ có nhúm đất. Cũng kể từ khi cây sung già này ra quả, công việc kinh doanh, làm ăn của anh thuận buồm xuôi gió, lộc đến đầy nhà, gia đình hạnh phúc. Chính vì vậy, cây sung này dù giá trị không cao, nhưng giá nào anh cũng không bán, bởi bán nó sợ mất lộc.
**Kinh hoàng giá cây cảnh!** **cây cảnh**có cái tên rất ẩm thực là “con gà mâm xôi”, hay “mâm xôi con gà”, thì nhuốm màu huyền thoại. ![ Cây cảnh](/uploads/news/2011_10/cay-canh18809-1.jpg)
**cây cảnh**đồn đoán rằng, hiện nó đang được cất giấu dưới Hà Nội. Có thể nó được gửi trong khu vườn bí mật nào đó của một đại gia chơi cây có máu mặt. ![ ](/uploads/news/2011_10/cay-canh18809.jpg)
**Tác giả bài viết:**Bá Hoàng [cây cảnh](/index.php?language=vi&nv=news&op=search&q=c%C3%A2y+c%E1%BA%A3nh), [nhật bản](/index.php?language=vi&nv=news&op=search&q=nh%E1%BA%ADt+b%E1%BA%A3n), [nghệ thuật](/index.php?language=vi&nv=news&op=search&q=ngh%E1%BB%87+thu%E1%BA%ADt), [việt nam](/index.php?language=vi&nv=news&op=search&q=vi%E1%BB%87t+nam), [choáng váng](/index.php?language=vi&nv=news&op=search&q=cho%C3%A1ng+v%C3%A1ng), [định giá](/index.php?language=vi&nv=news&op=search&q=%C4%91%E1%BB%8Bnh+gi%C3%A1), [lên đến](/index.php?language=vi&nv=news&op=search&q=l%C3%AAn+%C4%91%E1%BA%BFn), [tiền tỷ](/index.php?language=vi&nv=news&op=search&q=ti%E1%BB%81n+t%E1%BB%B7), [thậm chí](/index.php?language=vi&nv=news&op=search&q=th%E1%BA%ADm+ch%C3%AD), [triệu usd](/index.php?language=vi&nv=news&op=search&q=tri%E1%BB%87u+usd), [có giá](/index.php?language=vi&nv=news&op=search&q=c%C3%B3+gi%C3%A1), [triệu đô](/index.php?language=vi&nv=news&op=search&q=tri%E1%BB%87u+%C4%91%C3%B4), [theo giới](/index.php?language=vi&nv=news&op=search&q=theo+gi%E1%BB%9Bi), [sành chơi](/index.php?language=vi&nv=news&op=search&q=s%C3%A0nh+ch%C6%A1i), [cây phải](/index.php?language=vi&nv=news&op=search&q=c%C3%A2y+ph%E1%BA%A3i), [có tuổi](/index.php?language=vi&nv=news&op=search&q=c%C3%B3+tu%E1%BB%95i), [nhất và](/index.php?language=vi&nv=news&op=search&q=nh%E1%BA%A5t+v%C3%A0), [trăm năm](/index.php?language=vi&nv=news&op=search&q=tr%C4%83m+n%C4%83m), [sở thích](/index.php?language=vi&nv=news&op=search&q=s%E1%BB%9F+th%C3%ADch), [này không](/index.php?language=vi&nv=news&op=search&q=n%C3%A0y+kh%C3%B4ng), [chăm sóc](/index.php?language=vi&nv=news&op=search&q=ch%C4%83m+s%C3%B3c), [tỉa tót](/index.php?language=vi&nv=news&op=search&q=t%E1%BB%89a+t%C3%B3t), [như vậy](/index.php?language=vi&nv=news&op=search&q=nh%C6%B0+v%E1%BA%ADy), [sở hữu](/index.php?language=vi&nv=news&op=search&q=s%E1%BB%9F+h%E1%BB%AFu), [tâm linh](/index.php?language=vi&nv=news&op=search&q=t%C3%A2m+linh), [những cây](/index.php?language=vi&nv=news&op=search&q=nh%E1%BB%AFng+c%C3%A2y), [cây sanh](/index.php?language=vi&nv=news&op=search&q=c%C3%A2y+sanh), [dòng họ](/index.php?language=vi&nv=news&op=search&q=d%C3%B2ng+h%E1%BB%8D), [tỷ đồng](/index.php?language=vi&nv=news&op=search&q=t%E1%BB%B7+%C4%91%E1%BB%93ng), [cái giá](/index.php?language=vi&nv=news&op=search&q=c%C3%A1i+gi%C3%A1), [chính vì](/index.php?language=vi&nv=news&op=search&q=ch%C3%ADnh+v%C3%AC), [mua được](/index.php?language=vi&nv=news&op=search&q=mua+%C4%91%C6%B0%E1%BB%A3c), [gia thành](/index.php?language=vi&nv=news&op=search&q=gia+th%C3%A0nh), [trả giá](/index.php?language=vi&nv=news&op=search&q=tr%E1%BA%A3+gi%C3%A1), [hà nội](/index.php?language=vi&nv=news&op=search&q=h%C3%A0+n%E1%BB%99i), [người chơi](/index.php?language=vi&nv=news&op=search&q=ng%C6%B0%E1%BB%9Di+ch%C6%A1i), [tinh túy](/index.php?language=vi&nv=news&op=search&q=tinh+t%C3%BAy), [người thích](/index.php?language=vi&nv=news&op=search&q=ng%C6%B0%E1%BB%9Di+th%C3%ADch)
#### Những tin mới hơn
-
[Điêu đứng vì nạn trộm cây cảnh](/news/Tin-cay-canh/Dieu-dung-vi-nan-trom-cay-canh-55/)(14/10/2011)
-
[Triển lãm hơn 2.500 cây cảnh, non bộ Thăng Long](/news/Tin-cay-canh/Trien-lam-hon-2-500-cay-canh-non-bo-Thang-Long-54/)(14/10/2011)
-
[Hai thanh niên trộm cây cảnh quý bị bắt](/news/Tin-cay-canh/Hai-thanh-nien-trom-cay-canh-quy-bi-bat-53/)(14/10/2011)
-
[Cận cảnh cây ngoại lai xâm hại đầu tiên tại Lâm Đồng](/news/Tin-cay-canh/Can-canh-cay-ngoai-lai-xam-hai-dau-tien-tai-Lam-Dong-52/)(14/10/2011)
-
[Thăm vườn cảnh Nhật Bản](/news/Tin-cay-canh/Tham-vuon-canh-Nhat-Ban-51/)(11/10/2011)
#### Những tin cũ hơn
-
[Bonsai - Cây thế xưa](/news/Tin-cay-canh/Bonsai-Cay-the-xua-46/)(11/10/2011)
-
[Hội ngộ cây cảnh ba miền](/news/Tin-cay-canh/Hoi-ngo-cay-canh-ba-mien-42/)(10/10/2011)
-
[Trồng cây cảnh theo phong thủy](/news/Tin-cay-canh/Trong-cay-canh-theo-phong-thuy-34/)(07/10/2011)
-
[Cây đầu lân](/news/Tin-cay-canh/Cay-dau-lan-32/)(06/10/2011)
-
[Kỹ thuật tạo hình và chăm sóc bon sai](/news/Tin-cay-canh/Ky-thuat-tao-hinh-va-cham-soc-bon-sai-29/)(06/10/2011)
### Ý kiến bạn đọc
### Dịch vụ
[Trồng mới và chăm sóc cây công trình](/about/Trong-moi-va-cham-soc-cay-cong-trinh/)
Thế giới cây xanh xin kính chào quý khách! Với phương châm “ Mang lại thế giới XANH – SẠCH – ĐẸP cho bạn” Thế giới cây xanh được phát triển trên cái nôi của làng quê truyền thống với nghề cây cảnh Giới Tế – Phú Lâm – Tiên Du – Bắc Ninh. Nhằm đáp ứng nhu cầu chơi cây cảnh...
0916699856
### Tin cây cảnh được quan tâm
### Thế giới cây cảnh
-
[Cây cau ta](/cay-canh//Cay-cau-ta-12/)
-
**Giá:** **500 000 VND**
-
[Cây Chiêu Liêu](/cay-canh//Cay-Chieu-Lieu-81/)
-
[cây Sala đầu lân giống](/cay-canh//cay-Sala-dau-lan-giong-5/)
-
**Giá:** **180 000 VND**
-
[Cây sung lau năm](/cay-canh/Hoa-canh/Cay-sung-lau-nam-9/)
-
**Giá:** **55 000 000 VND**
-
[Trầu bà pháp](/cay-canh//Trau-ba-phap-14/)
-
[Cây cảnh để bàn Bạch Lan Chi](/cay-canh//Cay-canh-de-ban-Bach-Lan-Chi-19/)
### Dịch vụ vé máy bay
[Vé máy bay Hà Nội đi Đà Nẵng](http://trave.vn/view/230/ve-may-bay-ha-noi-di-da-nang.html), [Vé máy bay Hà Nội đi Buôn Ma Thuột](http://trave.vn/view/228/ve-may-bay-ha-noi-di-buon-ma-thuot-.html), [Vé máy bay Hà Nội đi Điện Biên](http://trave.vn/view/231/ve-may-bay-ha-noi-di-dien-bien.html), [Vé máy bay Hà Nội đi Hồ Chí Minh](http://trave.vn/view/245/ve-may-bay-ha-noi-di-ho-chi-minh.html), [Vé máy bay Hà Nội đi Phú Quốc](http://trave.vn/view/241/ve-may-bay-ha-noi-di-phu-quoc.html), [Vé máy bay Hà Nội đi Quy Nhơn](http://trave.vn/view/250/ve-may-bay-ha-noi-di-quy-nhon.html), [Vé máy bay Hà Nội đi Sài Gòn](http://trave.vn/view/246/ve-may-bay-ha-noi-di-sai-gon.html), [Vé máy bay Hà Nội đi Nha Trang](http://trave.vn/view/238/ve-may-bay-ha-noi-di-nha-trang.html), [Vé máy bay Hà Nội đi Đà Lạt](http://trave.vn/view/232/ve-may-bay-ha-noi-di-da-lat.html), [Vé máy bay Hà Nội đi Vinh](http://trave.vn/view/259/ve-may-bay-ha-noi-di-vinh.html)
Mã an toàn:
![ Mã chống spam](/index.php?scaptcha=captcha)

Server: DIGI-WebService

Set-Cookie: nv3c_Siich_nvvithemever=nA%2C%2C; expires=Mon, 23-Nov-2015 12:55:29 GMT; path=/; domain=.thegioicayxanh.com; httponly

Cache-Control: no-cache, pre-check=0, post-check=0

Content-Language: vi

Vary: Accept-Encoding,User-Agent


markdown:
Trở thành fan của Báo điện tử Tiền Phong trên Facebook để nhận tin hot nhất từ tienphong.vn
Báo điện tử Tiền Phong luôn mong muốn được nhận phản hồi từ bạn đọc! Mọi ý kiến hoặc bài vở đóng góp, xin vui lòng gửi về địa chỉ email:
Nếu bạn có tin tức thời sự nóng cần phản ánh trực tiếp, vui lòng liên lạc qua số điện thoại nóng sau:
01274.91.91.91

Set-Cookie: .ASPXANONYMOUS=UBrJUI_NTgBi5FZ3NBxz0WamEDRg7TWPS2_Diglc39Q7d5vvRkQUVSN7zDE_8Y2pvafBAjmzqsK79jWcJdMktcPPqfK8x6jcKt-tzJAkfjScOj6zEnSWbHt2LcsXM_pxj6ztbjrZs-NdLvHRlwEzQA2; domain=kienthuc.net.vn; expires=Sat, 31-Jan-2015 23:56:57 GMT; path=/; HttpOnly


markdown:
--------tra loi-----------
Khi gần đến ngày có kinh thì người nữ thuờng có huyết trắng nhưng không hôi và không gây triệu chứng khó chịu như cô nói.
Cô có thể đã bị viêm âm đạo. Theo những triệu chứng cô tả : ngứa, rát, đau thì cô có thể bị nhiễm nấm âm đạo, thường do nấm Candida abicans. Cũng có thể cô bị viêm âm đạo do vi trùng ( bacterial vaginosis ), loại nhiễm trùng nầy do các loại vi trùng xấu trong âm đạo như tạp trùng vô khí và Gardnerella phát triển nhiều hơn loại vi trùng tốt khi có . sự mất cân bằng môi trường acid trong âm đạo. Viêm âm đạo do nhiễm trùng cũng xảy ra do tiếp xúc tình dục, nhất là người mới có quan hệ tình dục và ngưòi có nhiều bạn tình khác nhau. Những ngưòi hay dùng vòi xịt để tắm, rửa âm đạo cũng dể bị nhiễm trùng âm đạo loại nầy..
Một đôi khi viêm âm đạo cũng do dị ứng do dùng nhiều xà bông có nhiều hoá chất nhất là xà bông có mùi thơm để rửa âm đạo.
Cô phải đến khám bác sĩ để đưọc thử nghiệm chất huyết trắng, tìm đúng nguyên nhân để được chữa trị thì mới hết được. Cô giữ gìn vệ sinh tốt vùng âm đạo, tắm hằng ngày, không dùng vòi xịt, không dùng xà bông có nhiều hoá chất, dầu thơm để rửa âm đạo. Mặc đồ lót nhẹ, không quá chật, khi đi ngủ không cần mặc đố lót. Nếu cô có quan hệ tình dục thì nên ngưng cho đến khi được chữa khỏi hẳn. Người bạn của cô phải mang bao cao su mổi khi có quan hệ, vừa tránh cho cô bị có thai ngoài ý muốn lại giúp tránh những bệnh lây nhiễm do tình dục như : gaing mai. lậu.mồng gà, viêm gan B,C HIV, nhiễm trùng âm đạo v..v
Nhiễm trùng âm đạo lâu ngày không chữa thì dể gây ra bệnh viêm vùng chậu và vi trùng có thể đi lên tử cung, vòi trứng gây ra những biến chứng ở những nơi nầy, ít nhiều cũng gây khó khăn cho việc sinh sản về sau.
Nếu bị nhiễm trong lúc có thai thì có thể gây sinh sớm hay bé sinh ra bị nhẹ cân.
Thân mến!
--------tra loi-----------
Bệnh huyết trắng gây ra do một loại nấm mốc tên là candida albicans, hiện diện thường trực trong tử cung. Thay vì âm thầm chịu đựng, bạn có nhiều cách để điều trị huyểt trắng bên cạnh việc dùng thuốc tây . nhưng đã hết bệnh chưa ?
Với phương thuốc gia truyền , chúng tôi bảo đảm hết bệnh mới thanh toán tiền (HỮU XÃ TỰ NHIÊN HƯƠNG mà).
CHúng tôi cam kết sẽ điều trị cho bạn . BAN HÃY YÊN TÂM
lIÊN HỆ VỚI CHÚNG TÔI :
Nickyahoo : PHONGTANHUYNH
email :
[phongtanhuynh@yahoo.com](mailto:phongtanhuynh@yahoo.com)
ĐT : 0.....57..6.0 _ Gặp Phong

Server: Apache/2.2.15 (CentOS)

Set-Cookie: SESSb96da813df6bb2c6a7a6af28d5bcedb2=iqpumnl51845jjqsf952pf2b24; expires=Tue, 16-Dec-2014 17:31:12 GMT; path=/; domain=.toitim.net

Cache-Control: post-check=0, pre-check=0


markdown:
Số lượng tác giả, tác phẩm tham gia Cuộc vận động..."Học tập và làm theo tấm gương đạo đức Hồ Chí Minh"
Những ngày hội guitar cổ điển quốc tế tại Việt Nam
Những bài viết khác
Biển mùa đông
Thanh Lam tổ chức đêm nhạc tưởng nhớ cha
Phiên bản mới cho vở kịch Dạ cổ hoài lang
Nhiếp ảnh nghệ thuật Việt Nam: còn đó những trăn trở
Triển lãm "Hình tượng sư tử và nghê trong nghệ thuật điêu khắc Việt Nam"
Nhà nguyện của a21studio – Việt Nam giành chiến thắng tại Festival kiến trúc thế giới 2014
Những câu hò trên quê hương Long An(phần 3)
VTV lần đầu phát sóng phim đóng mác 18+
Trang Thế Hy: Đại thụ tỏa bóng làng văn
Dòng văn học chống lại cái ác
Bộ sách mừng nhà văn Trang Thế Hy tròn 90 tuổi

Cache-Control: private, pre-check=0, post-check=0, max-age=0


markdown:
Gian hàng bán
Rao vặt
Hỏi đáp
Thêm
Danh sách gian hàng
Tin tức từ Vatgia.com
Để kinh doanh Online thành công
Đánh giá sản phẩm
BaoKim.vn
CucRe.vn
MyTour.vn
Nhanh.vn
WebBNC.net
Sản phẩm
Sản phẩm
Rao vặt
Hỏi đáp
Cửa hàng
Tìm trong danh mục
Dụng cụ tập luyện, thi đấu (Thể hình)
Dụng cụ tập bụng
Dụng cụ tập chân
Dụng cụ tập thể hình ngoài trời
Găng tay tập tạ
Ghế tập tạ
Giá để tạ
Tạ chân
Tạ tay
Tạ đĩa
Đòn tạ
Hỗ trợ
Tuyển dụng
Nạp tiền
Đăng ký
Đăng ký thành viên
Đăng ký gian hàng
Đăng nhập
Tên truy cập:
Mật khẩu:
Nhớ mật khẩu
Quên mật khẩu
Sản phẩm
Sản phẩm
Rao vặt
Hỏi đáp
Cửa hàng
Tìm trong danh mục
Dụng cụ tập luyện, thi đấu (Thể hình)
Dụng cụ tập bụng
Dụng cụ tập chân
Dụng cụ tập thể hình ngoài trời
Găng tay tập tạ
Ghế tập tạ
Giá để tạ
Tạ chân
Tạ tay
Tạ đĩa
Đòn tạ
Toàn bộ danh mục
Mua bán Các dụng cụ tập luyện, cac dung cu tap luyen giá tốt nhất
Dụng cụ tập bụng
Dụng cụ tập chân
Dụng cụ tập thể hình ngoài...
Găng tay tập tạ
Ghế tập tạ
Giá để tạ
Tạ chân
Tạ tay
Tạ đĩa
Đòn tạ
HOT nhất
Xem nhiều nhất
Thích nhiều nhất
Mua nhiều nhất
Ghế tập tạ đa năng PRO-DN30
940.000 VNĐ
Có
5
gian hàng bán
Máy tập cơ bụng Six Pack Care 2014 NEW
1.190.000 VNĐ
Có
7
gian hàng bán
Ghế tập tạ đa năng Pro-Care 501 thép...
690.000 VNĐ
Có
4
gian hàng bán
Ghế tập tạ đa năng - LA 501 Pro-Care
850.000 VNĐ
Có
4
gian hàng bán
Máy tập cơ bụng SIX PACK CARE PX - G06
1.000.000 VNĐ
Có
11
gian hàng bán
AD Flex - Máy tập bụng (Đỏ phối đen)
999.000 VNĐ
Có
1
gian hàng bán
Ghế tập tạ đa Năng Multy Ben 502N
4.900.000 VNĐ
Có
6
gian hàng bán
Ghế tập tạ có ép
840.000 VNĐ
Có
5
gian hàng bán
Ghế đẩy tạ LA401 - PRO CARE
550.000 VNĐ
Có
3
gian hàng bán
Mới cập nhật
Nhất tuần
Nhất tháng
Mới đổi giá
Dụng cụ tập luyện, thi đấu (Thể hình) nhất trong tháng
Tạ gang
16.900 VNĐ
Đĩa tạ ngang
18.000 VNĐ
Ghế tập Multy Ben 501
1.190.000 VNĐ
Ghế tập tạ đa năng Xuki XK01
890.000 VNĐ
Máy tập cơ bụng AD Roocket 2013A
290.000 VNĐ
Ghế tạ đa năng BEN501
2.940.000 VNĐ
Tạ tay nhựa 3kg TT205TTN01
7.000 VNĐ
Ghế nằm đẩy tạ Ben 301
580.000 VNĐ
Đòn tạ tay
89.000 VNĐ
Ghế tập tạ đa chức năng TV511002
940.000 VNĐ
Tạ tay thép S8020
70.000 VNĐ
Đòn tập tạ Động Lực BAR100
110.000 VNĐ
Ghế tập tạ đa năng Tuấn Vũ Sport
2.000.000 VNĐ / bộ
Tạ tay nhựa DCTT01
7.000 VNĐ
Ghế tạ sô MITU
1.240.000 VNĐ
Tạ tay trọn bộ 8.5kg DCTT08
160.000 VNĐ
Tạ đĩa nhựa
7.000 VNĐ
Ghế đẩy tạ đơn XK
690.000 VNĐ
Ghế tập tạ đơn LA-200
540.000 VNĐ
Tạ gang Olympic DCTT05
18.000 VNĐ
Ghế tập tạ đa năng LA-450
790.000 VNĐ
Tạ tay bọc nhựa
7.000 VNĐ
Ghế tạ đa năng Multi Bench 501
940.000 VNĐ
Ghế tập tạ đa năng thép vuông 30
930.000 VNĐ
Ghế lưng cong House Fit
380.000 VNĐ
Ghế tạ đa năng BEN501B
3.200.000 VNĐ
Ghế tạ lớn Marathon TL -2
1.270.000 VNĐ
Ghế tập tạ đa năng LA-350
780.000 VNĐ
Trang:
1
2
3
4
..
Mua bán Các dụng cụ tập luyện, cac dung cu tap luyen giá tốt nhất
Mua sắm
>
Dịch vụ, giải trí, du lịch
>
Thể thao
>
Thể dục thể hình
>
Dụng cụ tập luyện, thi đấu (Thể hình)
Gian hàng nhiều giao dịch nhất
.
1
Lazada Việt Nam
2
Cửa Hàng Dụng Cụ Y Khoa Bạch...
3
Công Ty TNHH Thể Thức 360 Độ
Sản phẩm nhiều người bán.
Ghế tập tạ đa năng LA401
790.000 VNĐ
4 gian hàng bán
Ghế tập thể hình đa năng - BEN 502 VIFA
4.200.000 VNĐ
3 gian hàng bán
Tin khuyến mại từ gian hàng đảm bảo.
CHUYÊN THỜI TRANG KIỂU HÀN QUỐC HOT NHẤT 2011
Trần thạch cao đẹp
Dán Phim chống nóng LLUMAR quà tặng đặc biệt
Camera Aptech AP-306
Jetstar - Mở bán vé máy bay Tết 2015 (Ất Mùi)
LỊCH 2014 - LỊCH SIÊU ĐẠI - SIÊU CỰC ĐẠI - GIÁ RẺ - CHIẾT KHẤU CAO
Tuyển dụng nhân viên SEO Website
điện thoại samsung galaxy note 4 xách tay singapo mới 100 %
Chỉ với 0 đồng phí vận chuyển, click thôi...
Giaythethao cùng bạn đón giáng sinh an lành
Xem tất cả
Rao vặt mới nhất
Dụng cụ thể hình chuyên nghiệp quang hải
Tạ đĩa 3 lỗ, tạ khối, tạ ăngte, thể hình Quang Hải
Khuyến mãi Thảm Tập Yoga chất lượng giá rẻ nhất tại Hà Nội -
150.000 VNĐ/ chiếc
Xe đạp thể dục hàn quốc SH_X 100 -
6.000.000 VNĐ
Máy tập six pack care da nang 6 lo xo -
1.350.000 VNĐ
Nhà sản xuất và cung cấp thiết bị thể hình chuyên nghiệp
Dụng cụ hít đất giá rẻ -
140.000 VNĐ/ cái
Chuyên sản xuất dụng cụ thể hình uy tín, lâu năm
Bạn đang muốn mở CLB Thể hình và đang tìm nhà sản xuất trong nước uy tín?
Tạ, đòn tạ, găng tay tập thể hình, dụng cụ tập thể hình, đai quấn bụng -
8.500 VNĐ
Xem tất cả
Hỏi đáp mới nhất.
Từ 5 đến 6 triệu nên mua điện thoại nào ạ?
Dưới 4 triệu nên mua điện thoại gì?
Xe máy dưới 30 triệu nên mua sản phẩm nào?
Tôi đang cần mua xe máy Honda với tầm tiền 16-17 triệu thì nên mua xe gì? ở đâu?
Tư vấn giúp em mua xe máy gì tầm 30 - 35tr?
Nên mua xe nào với tầm tiền 20 tr ạ?
Tầm 22 triệu nên mua xe máy nào???
Sinh viên sắp ra trường nên mua xe gì? mua tay ga hay mua xe số khi chỉ có dưới 30 triệu thôi
20tr mua xe gì?
Tư vấn mua xe tay ga dưới 30 triệu?
Xem tất cả
Vatgia.com
|
Sản phẩm
|
Rao vặt
|
Hỏi đáp, tư vấn tiêu dùng
|
Đánh giá (Review)
|
Lưu trữ rao vặt
|
iPhone 6
|
iPhone 6 Plus
|
iPad Air
|
Xe may
|
Dien thoai
|
Netbook
|
Máy tính laptop
|
Galaxy S5
|
Máy ảnh số
|
iPhone
|
Máy nghe nhạc MP3
|
Galaxy Tab
|
Tivi LCD
|
Mainboard
|
RAM
|
Màn hình LCD
|
Điều hòa
|
BlackBerry
|
Máy chấm công
|
Máy chiếu
|
Máy photocopy
|
Bat dong san
|
Can thue nha
|
Galaxy S4
|
iPhone 5
|
Sách
|
San go cong nghiep
|
iPhone 5S
|
Ao cuoi
|
Sàn gỗ công nghiệp
|
Ô tô
|
O to
|
Oto
|
Xe hơi
|
Tủ rack
|
Máy chụp cắt lớp
|
Áo dài nam
|
Khách sạn Thái Nguyên
|
Ghế băng công cộng
|
Máy giặt công nghiệp
|
Dây đeo, móc điện thoại
|
Khách sạn Lai Châu
|
Phim hành động, võ thuật
|
CPU Server
|
Rau, củ, quả
|
Máy đúc công nghiệp
Giới thiệu
|
Hướng dẫn
|
Quy chế hoạt động
|
Chính sách bảo mật thông tin
Công ty Cổ phần Vật Giá Việt Nam. Số GCNDT: 011032001615, cấp ngày 21/06/2012, nơi cấp: UBND thành phố Hà Nội. SĐT: 04 7308 0008
Trụ sở chính: Lê Đại Hành, Hai Bà Trưng, Hà Nội - Chi nhánh Hồ Chí Minh: Đường Lữ Gia, Phường 15, Quận 11, Hồ Chí Minh

Set-Cookie: u_nologin_id=1496748264; expires=Tue, 03-Mar-2015 13:49:05 GMT; path=/; httponly


markdown:
**1**lượt cảm ơn)
Máy tính VTB 2.2 (L7) (AMD Athlon 64 3500+ 2.2GHz, 1GB RAM, 80GB HDD, PC DOS, LCD VTB 17inch)
LENOVO THINKCENTRE M55E (8806-A64) , Intel Core 2 Duo Processor E4400 (2.0GHz 2MB L2 cache bus 800MHz ) , 1GB bus 533MHz DDRam2 , 160GB 7200rpm HDD , Free DOS , (không kèm màn hình)
HP DC7900SFF (Intel Core 2 Duo E7400 2.8GHz, 1GB RAM, 250GB HDD, VGA Intel GMA 4500, Windows Vista downgrade. không kèm theo màn hình )
HP Compaq dc7900 - E7400 (KP721AV) (Intel Core 2 Duo E7400 2.8GHz, 1GB RAM, 160GB HDD, VGA intel GMA 4500, Windows XP Pro, không kèm theo màn hình )
|
|![]()
|
|

Set-Cookie: u_nologin_id=1496735119; expires=Tue, 03-Mar-2015 13:40:57 GMT; path=/; httponly


markdown: **Từ :** **Đến :** [Hà Nội](/home/listudv.php?iCat=764&module=product&p1=44480&city_id=2)(68) [Hồ Chí Minh](/home/listudv.php?iCat=764&module=product&p1=44480&city_id=3)(67) [Hà Nội 2](/home/listudv.php?iCat=764&module=product&p1=44480&city_id=29)(67) [-](/home/listudv.php?iCat=764&module=product&p1=44480:224770)(+4) [1PLUS](/home/listudv.php?iCat=764&module=product&p1=44480:184180)(+4) [3M](/home/listudv.php?iCat=764&module=product&p1=44480:166225)(+4) [ACER](/home/listudv.php?iCat=764&module=product&p1=44480:44452)(+755) [ADI](/home/listudv.php?iCat=764&module=product&p1=44480:179837)(+17) [ADTEC](/home/listudv.php?iCat=764&module=product&p1=44480:44454)(+1) [ADVUEU](/home/listudv.php?iCat=764&module=product&p1=44480:46584)(+18) [AG NEOVO](/home/listudv.php?iCat=764&module=product&p1=44480:45265)(+87) [ALPHASCAN](/home/listudv.php?iCat=764&module=product&p1=44480:185002)(+2) [AMCOM](/home/listudv.php?iCat=764&module=product&p1=44480:224986)(+16) [AMPTRON](/home/listudv.php?iCat=764&module=product&p1=44480:45267)(+9) [AOC](/home/listudv.php?iCat=764&module=product&p1=44480:45268)(+346) [APIO](/home/listudv.php?iCat=764&module=product&p1=44480:167701)(+9) [APPLE](/home/listudv.php?iCat=764&module=product&p1=44480:44456)(+14) [ARCHTEX](/home/listudv.php?iCat=764&module=product&p1=44480:242001)(+5) [ASUS](/home/listudv.php?iCat=764&module=product&p1=44480:45269)(+415) [Balance](/home/listudv.php?iCat=764&module=product&p1=44480:401889)(+1) [BATESIAS](/home/listudv.php?iCat=764&module=product&p1=44480:169600)(+6) [BELINEA](/home/listudv.php?iCat=764&module=product&p1=44480:179852)(+53) [BENQ](/home/listudv.php?iCat=764&module=product&p1=44480:44457)(+297) [Braview](/home/listudv.php?iCat=764&module=product&p1=44480:441436)(+8) [BTC](/home/listudv.php?iCat=764&module=product&p1=44480:45270)(+6) [BUFFALO](/home/listudv.php?iCat=764&module=product&p1=44480:44458)(+3) [CANDELA](/home/listudv.php?iCat=764&module=product&p1=44480:44459)(+1) [CAPTIVA](/home/listudv.php?iCat=764&module=product&p1=44480:187386)(+1) [CHIMEI](/home/listudv.php?iCat=764&module=product&p1=44480:45271)(+63) [CODEGEN](/home/listudv.php?iCat=764&module=product&p1=44480:165792)(+19) [COLORTAC](/home/listudv.php?iCat=764&module=product&p1=44480:44462)(+3) [COLORVIEW](/home/listudv.php?iCat=764&module=product&p1=44480:145013)(+9) [COMPAQ](/home/listudv.php?iCat=764&module=product&p1=44480:187391)(+20) [CORNEA](/home/listudv.php?iCat=764&module=product&p1=44480:187463)(+4) [Cornerstone](/home/listudv.php?iCat=764&module=product&p1=44480:402616)(+1) [CTX](/home/listudv.php?iCat=764&module=product&p1=44480:402677)(+1) [DAEWOO](/home/listudv.php?iCat=764&module=product&p1=44480:116140)(+5) [DATACASK](/home/listudv.php?iCat=764&module=product&p1=44480:187467)(+1) [DELL](/home/listudv.php?iCat=764&module=product&p1=44480:91805)(+279) [DIGIMATE](/home/listudv.php?iCat=764&module=product&p1=44480:183200)(+36) [DIGITUS](/home/listudv.php?iCat=764&module=product&p1=44480:187471)(+6) [DINNER](/home/listudv.php?iCat=764&module=product&p1=44480:44464)(+1) [DNS](/home/listudv.php?iCat=764&module=product&p1=44480:349548)(+4) [DOUBLESIGHT](/home/listudv.php?iCat=764&module=product&p1=44480:45273)(+16) [E-YAMA](/home/listudv.php?iCat=764&module=product&p1=44480:187477)(+7) [EDGE10](/home/listudv.php?iCat=764&module=product&p1=44480:335575)(+3) [EIZO](/home/listudv.php?iCat=764&module=product&p1=44480:45274)(+311) [ELSA](/home/listudv.php?iCat=764&module=product&p1=44480:187552)(+8) [Emachines](/home/listudv.php?iCat=764&module=product&p1=44480:316044)(+23) [EMPREX](/home/listudv.php?iCat=764&module=product&p1=44480:179738)(+13) [ENVISION](/home/listudv.php?iCat=764&module=product&p1=44480:45275)(+33) [EPSON](/home/listudv.php?iCat=764&module=product&p1=44480:44466)(+1) [EVGA](/home/listudv.php?iCat=764&module=product&p1=44480:400338)(+1) [Eye-Q](/home/listudv.php?iCat=764&module=product&p1=44480:187583)(+6) [FORMAC](/home/listudv.php?iCat=764&module=product&p1=44480:187589)(+6) [FPT](/home/listudv.php?iCat=764&module=product&p1=44480:379148)(+3) [FUJIPLUS](/home/listudv.php?iCat=764&module=product&p1=44480:48821)(+7) [FUJITSU](/home/listudv.php?iCat=764&module=product&p1=44480:151523)(+211) [FUJITSU SIEMENS](/home/listudv.php?iCat=764&module=product&p1=44480:186626)(+28) [GATEWAY](/home/listudv.php?iCat=764&module=product&p1=44480:158480)(+29) [GIGABYTE](/home/listudv.php?iCat=764&module=product&p1=44480:148368)(+5) [GNR](/home/listudv.php?iCat=764&module=product&p1=44480:187235)(+4) [GoVideo](/home/listudv.php?iCat=764&module=product&p1=44480:99089)(+2) [GREAT WALL](/home/listudv.php?iCat=764&module=product&p1=44480:172880)(+77) [GREEN HOUSE](/home/listudv.php?iCat=764&module=product&p1=44480:44468)(+2) [GREENSYS](/home/listudv.php?iCat=764&module=product&p1=44480:142229)(+2) [GVISION](/home/listudv.php?iCat=764&module=product&p1=44480:185329)(+13) [HAIER](/home/listudv.php?iCat=764&module=product&p1=44480:92181)(+3) [HANNS-G](/home/listudv.php?iCat=764&module=product&p1=44480:45276)(+132) [HANNSPREE](/home/listudv.php?iCat=764&module=product&p1=44480:305447)(+22) [HANSOL](/home/listudv.php?iCat=764&module=product&p1=44480:188144)(+15) [HAZRO](/home/listudv.php?iCat=764&module=product&p1=44480:158198)(+6) [HCOM](/home/listudv.php?iCat=764&module=product&p1=44480:166109)(+8) [HERCULES](/home/listudv.php?iCat=764&module=product&p1=44480:188638)(+3) [HITACHI](/home/listudv.php?iCat=764&module=product&p1=44480:188775)(+25) [HKC](/home/listudv.php?iCat=764&module=product&p1=44480:191999)(+86) [HONEYWELL](/home/listudv.php?iCat=764&module=product&p1=44480:186536)(+2) [Hope or OEM](/home/listudv.php?iCat=764&module=product&p1=44480:404223)(+13) [HP-Compaq](/home/listudv.php?iCat=764&module=product&p1=44480:48642)(+264) [HYUNDAI](/home/listudv.php?iCat=764&module=product&p1=44480:44470)(+103) [I-INC](/home/listudv.php?iCat=764&module=product&p1=44480:341873)(+11) [IBM](/home/listudv.php?iCat=764&module=product&p1=44480:44471)(+48) [ICOM](/home/listudv.php?iCat=764&module=product&p1=44480:44472)(+2) [IIYAMA](/home/listudv.php?iCat=764&module=product&p1=44480:44473)(+231) [IODATA](/home/listudv.php?iCat=764&module=product&p1=44480:44474)(+12) [JETWAY](/home/listudv.php?iCat=764&module=product&p1=44480:192031)(+4) [JVC](/home/listudv.php?iCat=764&module=product&p1=44480:169690)(+1) [JVJ](/home/listudv.php?iCat=764&module=product&p1=44480:147271)(+3) [KDS](/home/listudv.php?iCat=764&module=product&p1=44480:45277)(+28) [KEYTEC](/home/listudv.php?iCat=764&module=product&p1=44480:169850)(+4) [KTC](/home/listudv.php?iCat=764&module=product&p1=44480:194187)(+42) [LACIE](/home/listudv.php?iCat=764&module=product&p1=44480:48679)(+14) [LENOVO](/home/listudv.php?iCat=764&module=product&p1=44480:44475)(+54) [LG](/home/listudv.php?iCat=764&module=product&p1=44480:44476)(+896) [Mace](/home/listudv.php?iCat=764&module=product&p1=44480:400689)(+6) [MAG](/home/listudv.php?iCat=764&module=product&p1=44480:44477)(+28) [Marshall](/home/listudv.php?iCat=764&module=product&p1=44480:401063)(+1) [Max](/home/listudv.php?iCat=764&module=product&p1=44480:401847)(+1) [Mercury](/home/listudv.php?iCat=764&module=product&p1=44480:420549)(+20) [Microtek](/home/listudv.php?iCat=764&module=product&p1=44480:401842)(+6) [MIRAI](/home/listudv.php?iCat=764&module=product&p1=44480:169284)(+2) [MIRAZA](/home/listudv.php?iCat=764&module=product&p1=44480:146971)(+2) [MIRO](/home/listudv.php?iCat=764&module=product&p1=44480:179741)(+6) [Mirus](/home/listudv.php?iCat=764&module=product&p1=44480:400991)(+1) [MITSUBISHI](/home/listudv.php?iCat=764&module=product&p1=44480:44478)(+23) [Mitsustar](/home/listudv.php?iCat=764&module=product&p1=44480:328878)(+9) [MOTV](/home/listudv.php?iCat=764&module=product&p1=44480:333928)(+2) [NANAO](/home/listudv.php?iCat=764&module=product&p1=44480:44479)(+1) [NIKO](/home/listudv.php?iCat=764&module=product&p1=44480:45281)(+1) [Norcent](/home/listudv.php?iCat=764&module=product&p1=44480:401102)(+1) [OTEK](/home/listudv.php?iCat=764&module=product&p1=44480:464913)(+1) [PACKARD BELL](/home/listudv.php?iCat=764&module=product&p1=44480:185357)(+7) [PANASONIC](/home/listudv.php?iCat=764&module=product&p1=44480:44484)(+11) [PHILIPS](/home/listudv.php?iCat=764&module=product&p1=44480:45282)(+393) [PIONEER](/home/listudv.php?iCat=764&module=product&p1=44480:169694)(+1) [PIXMANIA](/home/listudv.php?iCat=764&module=product&p1=44480:183831)(+2) [Planar](/home/listudv.php?iCat=764&module=product&p1=44480:325299)(+24) [PRESTIGIO](/home/listudv.php?iCat=764&module=product&p1=44480:322853)(+16) [PRINCETON](/home/listudv.php?iCat=764&module=product&p1=44480:44486)(+13) [PROLINK](/home/listudv.php?iCat=764&module=product&p1=44480:64322)(+23) [PROVIEW](/home/listudv.php?iCat=764&module=product&p1=44480:64358)(+50) [PSA](/home/listudv.php?iCat=764&module=product&p1=44480:48819)(+1) [QUATOGRAPHIC](/home/listudv.php?iCat=764&module=product&p1=44480:333929)(+2) [RICHWELL](/home/listudv.php?iCat=764&module=product&p1=44480:185609)(+4) [ROSEWILL](/home/listudv.php?iCat=764&module=product&p1=44480:45284)(+23) [SAMSUNG](/home/listudv.php?iCat=764&module=product&p1=44480:44488)(+678) [SANYO](/home/listudv.php?iCat=764&module=product&p1=44480:183716)(+3) [SCEPTRE](/home/listudv.php?iCat=764&module=product&p1=44480:45285)(+24) [SHARP](/home/listudv.php?iCat=764&module=product&p1=44480:44489)(+49) [SHUTTLE](/home/listudv.php?iCat=764&module=product&p1=44480:45286)(+1) [SONY](/home/listudv.php?iCat=764&module=product&p1=44480:44490)(+189) [SOTEC](/home/listudv.php?iCat=764&module=product&p1=44480:44491)(+1) [SOYO](/home/listudv.php?iCat=764&module=product&p1=44480:185003)(+4) [STARVIEW](/home/listudv.php?iCat=764&module=product&p1=44480:116139)(+8) [SUNVIEW](/home/listudv.php?iCat=764&module=product&p1=44480:412283)(+6) [SYNAPS](/home/listudv.php?iCat=764&module=product&p1=44480:289040)(+2) [Tatung](/home/listudv.php?iCat=764&module=product&p1=44480:401430)(+4) [TCL](/home/listudv.php?iCat=764&module=product&p1=44480:93714)(+3) [TOPICA](/home/listudv.php?iCat=764&module=product&p1=44480:183736)(+6) [TOPVIEW](/home/listudv.php?iCat=764&module=product&p1=44480:333461)(+16) [TOSHIBA](/home/listudv.php?iCat=764&module=product&p1=44480:44492)(+7) [TRIOTECH](/home/listudv.php?iCat=764&module=product&p1=44480:205357)(+43) [TYRIS](/home/listudv.php?iCat=764&module=product&p1=44480:49258)(+3) [V7](/home/listudv.php?iCat=764&module=product&p1=44480:398444)(+10) [VENR](/home/listudv.php?iCat=764&module=product&p1=44480:64292)(+21) [VIDEOSEVEN](/home/listudv.php?iCat=764&module=product&p1=44480:178990)(+67) [VIEWERA](/home/listudv.php?iCat=764&module=product&p1=44480:49297)(+20) [VIEWSONIC](/home/listudv.php?iCat=764&module=product&p1=44480:44494)(+334) [VISON](/home/listudv.php?iCat=764&module=product&p1=44480:246599)(+2) [VISSTAR](/home/listudv.php?iCat=764&module=product&p1=44480:186585)(+1) [VTB](/home/listudv.php?iCat=764&module=product&p1=44480:95949)(+5) [WESCOM](/home/listudv.php?iCat=764&module=product&p1=44480:187209)(+3) [WESTINGHOUSE](/home/listudv.php?iCat=764&module=product&p1=44480:185000)(+22) [WISE WING](/home/listudv.php?iCat=764&module=product&p1=44480:49260)(+4) [WORTMANN](/home/listudv.php?iCat=764&module=product&p1=44480:182857)(+25) [X2GEN](/home/listudv.php?iCat=764&module=product&p1=44480:49261)(+3) [XEROX](/home/listudv.php?iCat=764&module=product&p1=44480:184728)(+14) [YURAKU](/home/listudv.php?iCat=764&module=product&p1=44480:184189)(+40) [ZALMAN](/home/listudv.php?iCat=764&module=product&p1=44480:170384)(+5) [PLANAR](/home/listudv.php?iCat=764&module=product&p1=44480:46472)(+47) [≥ 15inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=15)(280) [≥ 17inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=17)(248) [≥ 18.5inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=18.5)(196) [≥ 19inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=19)(195) [≥ 21inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=21)(94) [≥ 23inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=23)(60) [≥ 24inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=24)(47) [≥ 32inch](/home/listudv.php?iCat=764&module=product&p1=44480&p5=32)(8)

Set-Cookie: u_nologin_id=1496735753; expires=Tue, 03-Mar-2015 13:41:18 GMT; path=/; httponly