一直以来对算法啊,数据结构神马的最害怕了,没办法,既然是选择计算机这个专业,这些都是必须的基本功,有人称其为内功,我觉得很正确。为了提高我的内功,最近开始啃买了两年就看了不到100页的《算法导论》,今天看到了数据结构这几章,就用C++模版实现了链表和二叉搜索树,比较简单就当是复习C++模版了。
1 template <class T> struct Node
2 {
3 T data;
4 Node *next;
5 };
6
7
8 template <class T> class MyList
9 {
10 private:
11 Node<T> *pHead;
12 public:
13 MyList(){
14 pHead = NULL;
15 }
16
17 Node* GetHead()
18 {
19 return pHead;
20 }
21
22 void SetHead(Node *head)
23 {
24 this->pHead = head;
25 }
26 void InsertNode(T value);
27 void PrintAll();
28 void ReverseList();
29 MyList<T> MergeList(MyList<T> list);
30 };
31
32 template <class T> MyList<T> MyList<T>::MergeList(MyList<T> list)
33 {
34 MyList<T> newList;
35 Node<T>* head1, *head2;
36 head1 = pHead;
37 head2 = list.pHead;
38 while (head1!=NULL && head2!=NULL)
39 {
40 if (head1->data>head2->data)
41 {
42 newList.InsertNode(head2->data);
43 head2 = head2->next;
44 }else
45 {
46 newList.InsertNode(head1->data);
47 head1 = head1->next;
48 }
49 }
50 while (head1!=NULL)
51 {
52 newList.InsertNode(head1->data);
53 head1 = head1->next;
54 }
55
56 while (head2!=NULL)
57 {
58 newList.InsertNode(head2->data);
59 head2 = head2->next;
60 }
61 return newList;
62 }
63
64 template <class T> void MyList<T>::ReverseList()
65 {
66 Node<T> *Current=NULL, *Next = NULL, *temp;
67 Current = pHead;
68 while (NULL != Current)
69 {
70 temp = Current->next;
71 Current->next = Next;
72 Next = Current;
73 Current = temp;
74 }
75 pHead = Next;
76 }
77
78 template <class T> void MyList<T>::InsertNode(T value)
79 {
80 Node<T> *node = new Node<T>;
81 node->data = value;
82 node->next = NULL;
83
84 if (NULL == pHead)
85 {
86 pHead = node;
87 }else
88 {
89 Node<T> *temp = pHead;
90 while (temp->next!=NULL)
91 {
92 temp = temp->next;
93 }
94 temp->next = node;
95 }
96 }
97
98 template<class T> void MyList<T>::PrintAll()
99 {
100 Node<T> *pNode = pHead;
101 while (NULL != pNode)
102 {
103 cout << pNode->data << " ";
104 pNode = pNode->next;
105 }
106 cout << endl;
107 }
二叉查找树
1 #include <stack>
2
3 template <class T> struct Node
4 {
5 Node *pleft;
6 Node *pright;
7 Node *parent;
8 T value;
9 };
10
11 template <class T> class BST
12 {
13 private:
14
15 public:
16 Node<T> *root;
17 BST(){
18 root = NULL;
19 }
20 void InsertNode(T value);
21 void InOrderTree(Node<T> *root);
22 Node<T>* SearchNode(T value);
23 Node<T>* TreeMin(Node<T>* node){
24 Node<T> *temp = node;
25 while (temp->pleft!=NULL)
26 {
27 temp = temp->pleft;
28 }
29 return temp;
30 }
31 T TreeMax(){
32 Node<T> *temp = root;
33 while (temp->pright != NULL)
34 {
35 temp = temp->pright;
36 }
37 return temp->value;
38 }
39 Node<T>* NodeSuccessor(Node<T>* node){
40 if(node->pright!=NULL)
41 return TreeMin(node->pright);
42 Node<T>* p=node->parent;
43 while (p!=NULL && p->pright == node)//p是node的最低祖先节点且p的左儿子也是node的祖先
44 { //这里使用p->pringht是满足这个就继续寻找的意思,也就是不应该满足p->right.
45 node = p;
46 p = p->parent;
47 }
48 return p;
49 }
50
51 Node<T>* DeleteNode(Node<T>* delNode)
52 {
53 Node<T>* temp = NULL, *x = NULL;
54 //找到要删除的结点temp,当delnode至多只有一个子女时temp=delnode, 有两个子女时temp为delnode的后继
55 if (delNode->pleft == NULL || NULL == delNode->pright)
56 {
57 temp = delNode;
58 }else
59 temp = NodeSuccessor(delNode);
60 //找到temp的非空子女,此时的temp只可能有一个子女,当temp无子女时置为NULL
61 if(temp->pleft!=NULL)
62 x = temp->pleft;
63 else
64 x = temp->pright;
65
66 //当x不为空的时候这时候不只是简单的删除temp就可以了,还要将temp->Parent与X连接起来
67 //这里是X到temp->Parent的链接,a
68 //这时需要将C连到a /
69 // b
70 // \
71 // c 相当于画从下到上的箭头
72 if(x!=NULL)
73 x->parent = temp->parent;
74
75 //需要删除的结点的父节点为空的时候,也就是要删除根节点,这时将temp的子女作为根节点
76 if(temp->parent == NULL)
77 root = x;
78 else{//不为空时判断temp是左子女还是右子女,画从上到下的箭头
79 if (temp == temp->parent->pleft)
80 {
81 temp->parent->pleft = x;
82 }else{
83 temp->parent->pright = x;
84 }
85 }
86
87 //当要删除的节点与temp不相等时,也就是当delNode有两个子女时,将temp的值赋于delNode,
88 //这时候树结构调整已经结束,只剩下只调整。
89 if (temp != delNode)
90 {
91 delNode->value = temp->value;
92 }
93 return temp;
94 }
95 };
96 template<class T> Node<T>* BST<T>::SearchNode(T value)
97 {
98 Node<T> *temp = root;
99 while (temp!=NULL)
100 {
101 if (value == temp->value)
102 {
103 break;
104 }
105 if(value > temp->value)
106 temp = temp->pright;
107 else
108 temp = temp->pleft;
109 }
110 return temp;
111 }
112
113 template<class T> void BST<T>::InOrderTree(Node<T> *root)
114 {
115 // if(root != NULL) //递归的中序遍历
116 // {
117 // InOrderTree(root->pleft);
118 // cout << root->value << " ";
119 // InOrderTree(root->pright);
120 // }
121
122 //利用栈进行中序遍历,就是不断地将左子树压栈直到最左子女为止,这时从栈中弹出栈顶元素(其实就是最左子女)
123 //并输出该元素的值,然后若其有子女不为空将其有子女压栈(其实就是先解决以这个右子女为根节点的子树)
124 stack<Node<T>*> st;
125 while (root!=NULL || !st.empty())
126 {
127 while (root!=NULL)
128 {
129 st.push(root);
130 root = root->pleft;
131 }
132 if (!st.empty())
133 {
134 Node<T>* node = st.top();
135 st.pop();
136 cout << node->value << " ";
137 root = node->pright;
138 }
139 }
140 }
141
142 template<class T> void BST<T>::InsertNode(T value)
143 {
144 Node<T> *node = new Node<T>;
145 node->parent = NULL;
146 node->pleft = NULL;
147 node->pright = NULL;
148 node->value = value;
149
150 Node<T> *p = NULL, *temp=root;
151 while (temp != NULL)
152 {
153 p = temp;
154 if(value < temp->value)
155 temp = temp->pleft;
156 else
157 temp = temp->pright;
158 }
159 node->parent = p;
160 if (p==NULL)
161 {
162 root = node;
163 }else
164 {
165 if(value > p->value)
166 p->pright = node;
167 else
168 p->pleft = node;
169 }
170 }
下面是测试二叉查找树的代码
1 int main(int argc, char* argv[])
2 {
3 BST<int> bst;
4 bst.InsertNode(3);
5 bst.InsertNode(5);
6 bst.InsertNode(4);
7 bst.InsertNode(2);
8 bst.InsertNode(1);
9
10 bst.InOrderTree(bst.root);
11 Node<int>* node = bst.SearchNode(3);
12 cout << endl;
13 cout << node->value << endl;
14 bst.DeleteNode(node);
15 bst.InOrderTree(bst.root);
16 //cout << bst.NodeSuccessor(node)->value << endl;
17 return 0;
18 }
浙公网安备 33010602011771号