【模板小程序】链表排序(qsort/insert_sort/merge_sort)
前言
本文章整理了链表排序的三种方法,分别是快速排序、插入排序、归并排序。为适应不同用途,先给出常用的int版本,再在此基础上抽象出类模板。
目录
一、针对整数的版本(常用)
- 文中链表定义
- 链表相关操作
- 三种排序方法
- 完整测试程序
二、模板版本(适用性广泛)
- 文中链表定义
- 链表相关操作
- 三种排序方法
- 完整测试程序
总结
参考文章
一、针对整数的版本(常用)
文中链表定义:
- //definition for singly-linked list.
- struct ListNode
- {
- int val;
- ListNode* next;
- ListNode(int x) : val(x), next(NULL) {}
- };
链表相关操作:
- //链表结点构造
- ListNode* create_list_node(int val)
- {
- ListNode* pNode = new ListNode(val);
- return pNode;
- }
- //链表结点连接
- void connect_list_node(ListNode* pCur, ListNode* pNext)
- {
- pCur->next = pNext;
- }
- //销毁单个节点(其实用这个更好,不会出现空悬指针)
- void destory_Node(ListNode** ppNode)
- {
- if(*ppNode != NULL)
- delete *ppNode;
- *ppNode = NULL;
- }
- //链表销毁(注意,除头节点外,其他节点均变成了空悬指针,不建议此用法)
- void destory_list(ListNode** ppHead)
- {
- ListNode** cur = ppHead;
- while(*cur != NULL)
- {
- ListNode* tmp = (*cur)->next;//保存下一个节点
- delete *cur;
- *cur = NULL;
- *cur = tmp;
- }
- }
- //链表打印(不支持有环的链表;如果链表有环,需判断环入口等等另外处理)
- void print_list(ListNode* pHead)
- {
- ListNode* cur = pHead;
- while(cur != NULL)
- {
- cout<< cur->val <<" ";
- cur = cur->next;
- }
- cout<<endl;
- }
三种排序方法:
- //链表快速排序
- class List_qsort
- {
- private:
- //交换元素
- void list_swap(int& lhs,int& rhs)
- {
- int tmp = lhs;
- lhs = rhs;
- rhs = tmp;
- }
- //划分,使左边小于头结点元素,右边大于等于头结点元素
- ListNode* list_partion(ListNode* pBegin,ListNode* pEnd)
- {
- if(pBegin == pEnd || pBegin->next == NULL)
- return pBegin;
- ListNode* pSlow=pBegin;
- ListNode* pFast=pBegin;
- int key=pBegin->val;
- while(pFast != pEnd)
- {
- if(pFast->val < key)
- {
- pSlow = pSlow->next;
- list_swap(pSlow->val,pFast->val);
- }
- pFast = pFast->next;
- }
- list_swap(pSlow->val,pBegin->val);
- return pSlow;
- }
- //排序辅助函数
- void _list_qsort(ListNode* pBegin,ListNode* pEnd)
- {
- if(pBegin == pEnd || NULL == pBegin->next)
- return;
- ListNode* mid=list_partion(pBegin,pEnd);
- _list_qsort(pBegin,mid);
- _list_qsort(mid->next,pEnd);
- }
- public:
- //排序入口函数(版本1:传值)
- void list_qsort(ListNode* pHead)
- {
- if(pHead == NULL || pHead->next ==NULL)
- return ;
- _list_qsort(pHead,NULL);
- }
- /*
- //排序入口函数(版本2:传指针)
- void list_qsort(ListNode** ppHead)
- {
- if(*ppHead == NULL || (*ppHead)->next ==NULL)
- return;
- _list_qsort(*ppHead,NULL);
- }
- */
- /*
- //排序入口函数(版本3:传引用)
- void list_qsort(ListNode*& pHead)
- {
- if(NULL == pHead || NULL == pHead->next )
- return;
- _list_qsort(pHead,NULL);
- }
- */
- };
- //链表插入排序
- class List_insertion_sort
- {
- //版本1:指针的指针
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode** ppNode, ListNode *pNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(pNode->val < (*ppNode)->val)
- {
- pNode->next = *ppNode;
- (*ppNode) = pNode;
- return;
- }
- cur = *ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode** ppNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(NULL == ppNode || NULL == *ppNode)
- return;
- cur = (*ppNode)->next;
- (*ppNode)->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- /*
- //版本2:指针的引用
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode*& ppNode, ListNode *pNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(pNode->val < ppNode->val)
- {
- pNode->next = ppNode;
- ppNode = pNode;
- return;
- }
- cur = ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode*& ppNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(NULL == ppNode)
- return;
- cur = ppNode->next;
- ppNode->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- */
- };
- //链表归并排序
- class List_merge_sort
- {
- private:
- //合并两端链表
- //因为可能在头结点之前插入数据,故为ListNode** list1
- ListNode* list_merge(ListNode* list1, ListNode* list2)
- {
- if(NULL == list1)
- return list2;
- else if(NULL == list2)
- return list1;
- ListNode* dummy = new ListNode(-);//辅助头结点
- dummy->next = list1;
- ListNode* list1_cur = dummy;
- ListNode* list2_cur = list2;
- while(list1_cur->next != NULL && list2_cur != NULL)
- {
- //cout<< list1_cur->next->val <<"==="<< list2_cur->val<<endl;
- //把后面一段list2更小的元素插入前面一段list1中
- if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
- {
- list2 = list2->next;
- list2_cur->next = list1_cur->next;
- list1_cur->next = list2_cur;
- list1_cur = list2_cur;
- list2_cur = list2;
- }
- else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
- list1_cur = list1_cur->next;
- }
- //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
- if(NULL == list1_cur->next)
- list1_cur->next = list2_cur;
- ListNode* pHead = dummy->next;
- delete dummy;//释放dummy
- return pHead;//返回头结点
- }
- //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode** pHead)
- ListNode* _list_merge_sort(ListNode** pHead)
- {
- if(NULL == *pHead || NULL == (*pHead)->next)
- return *pHead;
- ListNode* pSlow = *pHead;
- ListNode* pFast = *pHead;
- while(pFast->next !=NULL && pFast->next->next !=NULL)
- {
- pSlow = pSlow->next;
- pFast = pFast->next->next;
- }
- ListNode* pLeftHead = *pHead;
- ListNode* pRightHead = pSlow->next;
- pSlow->next = NULL;//左半链表尾节点的next赋空值
- /*pLeftHead = */_list_merge_sort(&pLeftHead);
- /*pRightHead = */_list_merge_sort(&pRightHead);
- //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部
- //的的next可能已经变了,因此他们可能伸长或缩短
- *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
- return *pHead;
- }
- public:
- //归并排序入口,去掉了返回值,不包装这一层也行
- void list_merge_sort(ListNode** pHead)
- {
- _list_merge_sort(pHead);//注意这里传入的是地址
- }
- };
完整测试程序:
- /*
- 本程序说明:
- 链表排序各种方法(快速排序)
- 参考链接:
- http://blog.csdn.net/u012658346/article/details/51141288
- http://www.jb51.net/article/37300.htm
- */
- #include <iostream>
- using namespace std;
- //definition for singly-linked list.
- struct ListNode
- {
- int val;
- ListNode* next;
- ListNode(int x) : val(x), next(NULL) {}
- };
- //链表结点构造
- ListNode* create_list_node(int val)
- {
- ListNode* pNode = new ListNode(val);
- return pNode;
- }
- //链表结点连接
- void connect_list_node(ListNode* pCur, ListNode* pNext)
- {
- pCur->next = pNext;
- }
- //销毁单个节点(其实用这个更好,不会出现空悬指针)
- void destory_Node(ListNode** ppNode)
- {
- if(*ppNode != NULL)
- delete *ppNode;
- *ppNode = NULL;
- }
- //链表销毁(注意,除头节点外,其他节点均变成了空悬指针)
- void destory_list(ListNode** ppHead)
- {
- ListNode** cur = ppHead;
- while(*cur != NULL)
- {
- ListNode* tmp = (*cur)->next;//保存下一个节点
- delete *cur;
- *cur = NULL;
- *cur = tmp;
- }
- }
- //链表打印
- void print_list(ListNode* pHead)
- {
- ListNode* cur = pHead;
- while(cur != NULL)
- {
- cout<< cur->val <<" ";
- cur = cur->next;
- }
- cout<<endl;
- }
- //链表快速排序
- class List_qsort
- {
- private:
- //交换元素
- void list_swap(int& lhs,int& rhs)
- {
- int tmp = lhs;
- lhs = rhs;
- rhs = tmp;
- }
- //划分,使左边小于头结点元素,右边大于等于头结点元素
- ListNode* list_partion(ListNode* pBegin,ListNode* pEnd)
- {
- if(pBegin == pEnd || pBegin->next == NULL)
- return pBegin;
- ListNode* pSlow=pBegin;
- ListNode* pFast=pBegin;
- int key=pBegin->val;
- while(pFast != pEnd)
- {
- if(pFast->val < key)
- {
- pSlow = pSlow->next;
- list_swap(pSlow->val,pFast->val);
- }
- pFast = pFast->next;
- }
- list_swap(pSlow->val,pBegin->val);
- return pSlow;
- }
- //排序辅助函数
- void _list_qsort(ListNode* pBegin,ListNode* pEnd)
- {
- if(pBegin == pEnd || NULL == pBegin->next)
- return;
- ListNode* mid=list_partion(pBegin,pEnd);
- _list_qsort(pBegin,mid);
- _list_qsort(mid->next,pEnd);
- }
- public:
- //排序入口函数(版本1:传值)
- void list_qsort(ListNode* pHead)
- {
- if(pHead == NULL || pHead->next ==NULL)
- return ;
- _list_qsort(pHead,NULL);
- }
- /*
- //排序入口函数(版本2:传指针)
- void list_qsort(ListNode** ppHead)
- {
- if(*ppHead == NULL || (*ppHead)->next ==NULL)
- return;
- _list_qsort(*ppHead,NULL);
- }
- */
- /*
- //排序入口函数(版本3:传引用)
- void list_qsort(ListNode*& pHead)
- {
- if(NULL == pHead || NULL == pHead->next )
- return;
- _list_qsort(pHead,NULL);
- }
- */
- };
- //链表插入排序
- class List_insertion_sort
- {
- //版本1:指针的指针
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode** ppNode, ListNode *pNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(pNode->val < (*ppNode)->val)
- {
- pNode->next = *ppNode;
- (*ppNode) = pNode;
- return;
- }
- cur = *ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode** ppNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(NULL == ppNode || NULL == *ppNode)
- return;
- cur = (*ppNode)->next;
- (*ppNode)->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- /*
- //版本2:指针的引用
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode*& ppNode, ListNode *pNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(pNode->val < ppNode->val)
- {
- pNode->next = ppNode;
- ppNode = pNode;
- return;
- }
- cur = ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode*& ppNode)
- {
- ListNode* prev = NULL;
- ListNode* cur = NULL;
- if(NULL == ppNode)
- return;
- cur = ppNode->next;
- ppNode->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- */
- };
- //链表归并排序
- class List_merge_sort
- {
- private:
- //合并两端链表
- //因为可能在头结点之前插入数据,故为ListNode** list1
- ListNode* list_merge(ListNode* list1, ListNode* list2)
- {
- if(NULL == list1)
- return list2;
- else if(NULL == list2)
- return list1;
- ListNode* dummy = new ListNode(-);//辅助头结点
- dummy->next = list1;
- ListNode* list1_cur = dummy;
- ListNode* list2_cur = list2;
- while(list1_cur->next != NULL && list2_cur != NULL)
- {
- //cout<< list1_cur->next->val <<"==="<< list2_cur->val<<endl;
- //把后面一段list2更小的元素插入前面一段list1中
- if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
- {
- list2 = list2->next;
- list2_cur->next = list1_cur->next;
- list1_cur->next = list2_cur;
- list1_cur = list2_cur;
- list2_cur = list2;
- }
- else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
- list1_cur = list1_cur->next;
- }
- //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
- if(NULL == list1_cur->next)
- list1_cur->next = list2_cur;
- ListNode* pHead = dummy->next;
- delete dummy;//释放dummy
- return pHead;//返回头结点
- }
- //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode** pHead)
- ListNode* _list_merge_sort(ListNode** pHead)
- {
- if(NULL == *pHead || NULL == (*pHead)->next)
- return *pHead;
- ListNode* pSlow = *pHead;
- ListNode* pFast = *pHead;
- while(pFast->next !=NULL && pFast->next->next !=NULL)
- {
- pSlow = pSlow->next;
- pFast = pFast->next->next;
- }
- ListNode* pLeftHead = *pHead;
- ListNode* pRightHead = pSlow->next;
- pSlow->next = NULL;//左半链表尾节点的next赋空值
- /*pLeftHead = */_list_merge_sort(&pLeftHead);
- /*pRightHead = */_list_merge_sort(&pRightHead);
- //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部
- //的的next可能已经变了,因此他们可能伸长或缩短
- *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
- return *pHead;
- }
- public:
- //归并排序入口,去掉了返回值,不包装这一层也行
- void list_merge_sort(ListNode** pHead)
- {
- _list_merge_sort(pHead);//注意这里传入的是地址
- }
- };
- //链表快速排序(测试样例)
- void test_list_qsort()
- {
- //创建结点
- ListNode* pNode1 = create_list_node();
- ListNode* pNode2 = create_list_node();
- ListNode* pNode3 = create_list_node();
- ListNode* pNode4 = create_list_node();
- ListNode* pNode5 = create_list_node(-);
- ListNode* pNode6 = create_list_node();
- ListNode* pNode7 = create_list_node();
- ListNode* pNode8 = create_list_node();
- ListNode* pNode9 = create_list_node(-);
- //连接结点
- connect_list_node(pNode1,pNode2);
- connect_list_node(pNode2,pNode3);
- connect_list_node(pNode3,pNode4);
- connect_list_node(pNode4,pNode5);
- connect_list_node(pNode5,pNode6);
- connect_list_node(pNode6,pNode7);
- connect_list_node(pNode7,pNode8);
- connect_list_node(pNode8,pNode9);
- //打印链表
- print_list(pNode1);
- //快速排序
- List_qsort test_qsort;
- test_qsort.list_qsort(pNode1);//传值
- //test_qsort.list_qsort(&pNode1);//传指针
- //test_qsort.list_qsort(pNode1);//传引用
- print_list(pNode1);
- /**********销毁链表(我们一般用到的方法,会出现空悬指针)********************/
- // destory_list(&pNode1);
- // //注意,释放链表后,头结点为NULL,其余的虽然释放了,但地址还在,因此成为空悬指针,需要进一步释放
- // //从这个角度来看,还不如写个函数释放每个节点,因此写了一个
- // if(pNode1)
- // print_list(pNode1);
- // else
- // cout<<"-1"<<endl;
- /***********************************************************************/
- /****************销毁链表(逐个销毁,不会出现空悬指针)*********************/
- destory_Node(&pNode1);
- destory_Node(&pNode2);
- destory_Node(&pNode3);
- destory_Node(&pNode4);
- destory_Node(&pNode5);
- destory_Node(&pNode6);
- destory_Node(&pNode7);
- destory_Node(&pNode8);
- destory_Node(&pNode9);
- // if(pNode1)
- // print_list(pNode1);
- // else
- // cout<<"-1"<<endl;
- /***********************************************************************/
- }
- //链表插入排序(测试样例)
- void test_list_insertion_sort()
- {
- //创建结点
- ListNode* pNode1 = create_list_node();
- ListNode* pNode2 = create_list_node();
- ListNode* pNode3 = create_list_node();
- ListNode* pNode4 = create_list_node();
- ListNode* pNode5 = create_list_node(-);
- ListNode* pNode6 = create_list_node();
- ListNode* pNode7 = create_list_node();
- ListNode* pNode8 = create_list_node();
- ListNode* pNode9 = create_list_node(-);
- //连接结点
- connect_list_node(pNode1,pNode2);
- connect_list_node(pNode2,pNode3);
- connect_list_node(pNode3,pNode4);
- connect_list_node(pNode4,pNode5);
- connect_list_node(pNode5,pNode6);
- connect_list_node(pNode6,pNode7);
- connect_list_node(pNode7,pNode8);
- connect_list_node(pNode8,pNode9);
- //打印链表
- print_list(pNode1);
- //插入排序
- List_insertion_sort test_insertion_sort;
- test_insertion_sort.list_insert_sort(&pNode1);//传指针
- //test_insertion_sort.list_insert_sort(pNode1);//传引用
- print_list(pNode1);
- }
- //链表归并排序(测试样例)
- void test_list_merge_sort()
- {
- //创建结点
- ListNode* pNode1 = create_list_node(-);
- ListNode* pNode2 = create_list_node(-);
- ListNode* pNode3 = create_list_node();
- ListNode* pNode4 = create_list_node();
- ListNode* pNode5 = create_list_node(-);
- ListNode* pNode6 = create_list_node();
- ListNode* pNode7 = create_list_node(-);
- ListNode* pNode8 = create_list_node();
- //ListNode* pNode9 = create_list_node(-7);
- //连接结点
- connect_list_node(pNode1,pNode2);
- connect_list_node(pNode2,pNode3);
- connect_list_node(pNode3,pNode4);
- connect_list_node(pNode4,pNode5);
- connect_list_node(pNode5,pNode6);
- connect_list_node(pNode6,pNode7);
- connect_list_node(pNode7,pNode8);
- //connect_list_node(pNode8,pNode9);
- //打印链表
- print_list(pNode1);
- //归并排序
- List_merge_sort test_merge_sort;
- //ListNode* p=test_merge_sort.list_merge_sort(&pNode1);//传指针
- test_merge_sort.list_merge_sort(&pNode1);
- print_list(pNode1);
- }
- int main()
- {
- cout<<"测试程序:"<<endl<<endl;
- cout<<"链表快速排序:"<<endl;
- test_list_qsort();
- cout<<endl;
- cout<<"链表插入排序:"<<endl;
- test_list_insertion_sort();
- cout<<endl;
- cout<<"链表归并排序:"<<endl;
- test_list_merge_sort();
- cout<<endl;
- return ;
- return ;
- }
二、模板版本(适用性广泛)
文中链表定义:
- //definition for singly-linked list.
- template <typename T>
- struct ListNode
- {
- T val;
- ListNode<T>* next;
- ListNode(T x) : val(x), next(NULL) {}
- };
链表相关操作:
- //链表结点构造
- template <typename T>
- ListNode<T>* create_list_node(T val)
- {
- ListNode<T>* pNode = new ListNode<T>(val);
- return pNode;
- }
- //链表结点连接
- template <typename T>
- void connect_list_node(ListNode<T>* pCur, ListNode<T>* pNext)
- {
- pCur->next = pNext;
- }
- //销毁单个节点(其实用这个更好,不会出现空悬指针)
- template <typename T>
- void destory_Node(ListNode<T>** ppNode)
- {
- if(*ppNode != NULL)
- delete *ppNode;
- *ppNode = NULL;
- }
- //链表销毁(注意,除头节点外,其他节点均变成了空悬指针,不建议此种方法)
- template <typename T>
- void destory_list(ListNode<T>** ppHead)
- {
- ListNode<T>** cur = ppHead;
- while(*cur != NULL)
- {
- ListNode<T>* tmp = (*cur)->next;//保存下一个节点
- delete *cur;
- *cur = NULL;
- *cur = tmp;
- }
- }
- //链表打印
- template <typename T>
- void print_list(ListNode<T>* pHead)
- {
- ListNode<T>* cur = pHead;
- while(cur != NULL)
- {
- cout<< cur->val <<" ";
- cur = cur->next;
- }
- cout<<endl;
- }
三种排序方法:
- //链表快速排序
- template <typename T>
- class List_qsort
- {
- private:
- //划分,使左边小于头结点元素,右边大于等于头结点元素
- ListNode<T>* list_partion(ListNode<T>* pBegin,ListNode<T>* pEnd)
- {
- if(pBegin == pEnd || pBegin->next == NULL)
- return pBegin;
- ListNode<T>* pSlow=pBegin;
- ListNode<T>* pFast=pBegin;
- ListNode<T>* pKey=new ListNode<T>(pBegin->val);//只为了保存用于比较的val
- while(pFast != pEnd)
- {
- if(pFast->val < pKey->val)
- {
- pSlow = pSlow->next;
- swap(pSlow->val,pFast->val);
- }
- pFast = pFast->next;
- }
- swap(pSlow->val,pBegin->val);
- delete pKey;//释放pKey
- return pSlow;
- }
- //排序辅助函数
- void _list_qsort(ListNode<T>* pBegin,ListNode<T>* pEnd)
- {
- if(pBegin == pEnd || NULL == pBegin->next)
- return;
- ListNode<T>* mid=list_partion(pBegin,pEnd);
- _list_qsort(pBegin,mid);
- _list_qsort(mid->next,pEnd);
- }
- public:
- //排序入口函数(版本1:传值)
- void list_qsort(ListNode<T>* pHead)
- {
- if(pHead == NULL || pHead->next ==NULL)
- return ;
- _list_qsort(pHead,NULL);
- }
- /*
- //排序入口函数(版本2:传指针)
- void list_qsort(ListNode<T>** ppHead)
- {
- if(*ppHead == NULL || (*ppHead)->next ==NULL)
- return;
- _list_qsort(*ppHead,NULL);
- }
- */
- /*
- //排序入口函数(版本3:传引用)
- void list_qsort(ListNode<T>*& pHead)
- {
- if(NULL == pHead || NULL == pHead->next )
- return;
- _list_qsort(pHead,NULL);
- }
- */
- };
- //链表插入排序
- template <typename T>
- class List_insertion_sort
- {
- //版本1:指针的指针
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode<T>** ppNode, ListNode<T>* pNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(pNode->val < (*ppNode)->val)
- {
- pNode->next = *ppNode;
- (*ppNode) = pNode;
- return;
- }
- cur = *ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode<T>** ppNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(NULL == ppNode || NULL == *ppNode)
- return;
- cur = (*ppNode)->next;
- (*ppNode)->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- /*
- //版本2:指针的引用
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode<T>*& ppNode, ListNode<T> *pNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(pNode->val < ppNode->val)
- {
- pNode->next = ppNode;
- ppNode = pNode;
- return;
- }
- cur = ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode<T>*& ppNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(NULL == ppNode)
- return;
- cur = ppNode->next;
- ppNode->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- */
- };
- //链表归并排序
- template <typename T>
- class List_merge_sort
- {
- private:
- //合并两端链表
- //因为可能在头结点之前插入数据,故为ListNode<T>** list1
- ListNode<T>* list_merge(ListNode<T>* list1, ListNode<T>* list2)
- {
- if(NULL == list1)
- return list2;
- else if(NULL == list2)
- return list1;
- ListNode<T>* dummy = new ListNode<T>(-);//辅助头结点
- dummy->next = list1;
- ListNode<T>* list1_cur = dummy;
- ListNode<T>* list2_cur = list2;
- while(list1_cur->next != NULL && list2_cur != NULL)
- {
- //cout<< list1_cur->next->val <<"==="<< list2_cur->val<<endl;
- //把后面一段list2更小的元素插入前面一段list1中
- if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
- {
- list2 = list2->next;
- list2_cur->next = list1_cur->next;
- list1_cur->next = list2_cur;
- list1_cur = list2_cur;
- list2_cur = list2;
- }
- else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
- list1_cur = list1_cur->next;
- }
- //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
- if(NULL == list1_cur->next)
- list1_cur->next = list2_cur;
- ListNode<T>* pHead = dummy->next;
- delete dummy;//释放dummy
- return pHead;//返回头结点
- }
- //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode<T>** pHead)
- ListNode<T>* _list_merge_sort(ListNode<T>** pHead)
- {
- if(NULL == *pHead || NULL == (*pHead)->next)
- return *pHead;
- ListNode<T>* pSlow = *pHead;
- ListNode<T>* pFast = *pHead;
- while(pFast->next !=NULL && pFast->next->next !=NULL)
- {
- pSlow = pSlow->next;
- pFast = pFast->next->next;
- }
- ListNode<T>* pLeftHead = *pHead;
- ListNode<T>* pRightHead = pSlow->next;
- pSlow->next = NULL;//左半链表尾节点的next赋空值
- /*pLeftHead = */_list_merge_sort(&pLeftHead);
- /*pRightHead = */_list_merge_sort(&pRightHead);
- //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部
- //的的next可能已经变了,因此他们可能伸长或缩短
- *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
- return *pHead;
- }
- public:
- //归并排序入口,去掉了返回值,不包装这一层也行
- void list_merge_sort(ListNode<T>** pHead)
- {
- _list_merge_sort(pHead);//注意这里传入的是地址
- }
- };
完整测试程序:
- /*
- 本程序说明:
- 链表排序各种方法(快速排序)
- 参考链接:
- http://blog.csdn.net/u012658346/article/details/51141288
- http://www.jb51.net/article/37300.htm
- */
- #include <iostream>
- using namespace std;
- //definition for singly-linked list.
- template <typename T>
- struct ListNode
- {
- T val;
- ListNode<T>* next;
- ListNode(T x) : val(x), next(NULL) {}
- };
- //链表结点构造
- template <typename T>
- ListNode<T>* create_list_node(T val)
- {
- ListNode<T>* pNode = new ListNode<T>(val);
- return pNode;
- }
- //链表结点连接
- template <typename T>
- void connect_list_node(ListNode<T>* pCur, ListNode<T>* pNext)
- {
- pCur->next = pNext;
- }
- //销毁单个节点(其实用这个更好,不会出现空悬指针)
- template <typename T>
- void destory_Node(ListNode<T>** ppNode)
- {
- if(*ppNode != NULL)
- delete *ppNode;
- *ppNode = NULL;
- }
- //链表销毁(注意,除头节点外,其他节点均变成了空悬指针)
- template <typename T>
- void destory_list(ListNode<T>** ppHead)
- {
- ListNode<T>** cur = ppHead;
- while(*cur != NULL)
- {
- ListNode<T>* tmp = (*cur)->next;//保存下一个节点
- delete *cur;
- *cur = NULL;
- *cur = tmp;
- }
- }
- //链表打印
- template <typename T>
- void print_list(ListNode<T>* pHead)
- {
- ListNode<T>* cur = pHead;
- while(cur != NULL)
- {
- cout<< cur->val <<" ";
- cur = cur->next;
- }
- cout<<endl;
- }
- //链表快速排序
- template <typename T>
- class List_qsort
- {
- private:
- //划分,使左边小于头结点元素,右边大于等于头结点元素
- ListNode<T>* list_partion(ListNode<T>* pBegin,ListNode<T>* pEnd)
- {
- if(pBegin == pEnd || pBegin->next == NULL)
- return pBegin;
- ListNode<T>* pSlow=pBegin;
- ListNode<T>* pFast=pBegin;
- ListNode<T>* pKey=new ListNode<T>(pBegin->val);//只为了保存用于比较的val
- while(pFast != pEnd)
- {
- if(pFast->val < pKey->val)
- {
- pSlow = pSlow->next;
- swap(pSlow->val,pFast->val);
- }
- pFast = pFast->next;
- }
- swap(pSlow->val,pBegin->val);
- delete pKey;//释放pKey
- return pSlow;
- }
- //排序辅助函数
- void _list_qsort(ListNode<T>* pBegin,ListNode<T>* pEnd)
- {
- if(pBegin == pEnd || NULL == pBegin->next)
- return;
- ListNode<T>* mid=list_partion(pBegin,pEnd);
- _list_qsort(pBegin,mid);
- _list_qsort(mid->next,pEnd);
- }
- public:
- //排序入口函数(版本1:传值)
- void list_qsort(ListNode<T>* pHead)
- {
- if(pHead == NULL || pHead->next ==NULL)
- return ;
- _list_qsort(pHead,NULL);
- }
- /*
- //排序入口函数(版本2:传指针)
- void list_qsort(ListNode<T>** ppHead)
- {
- if(*ppHead == NULL || (*ppHead)->next ==NULL)
- return;
- _list_qsort(*ppHead,NULL);
- }
- */
- /*
- //排序入口函数(版本3:传引用)
- void list_qsort(ListNode<T>*& pHead)
- {
- if(NULL == pHead || NULL == pHead->next )
- return;
- _list_qsort(pHead,NULL);
- }
- */
- };
- //链表插入排序
- template <typename T>
- class List_insertion_sort
- {
- //版本1:指针的指针
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode<T>** ppNode, ListNode<T>* pNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(pNode->val < (*ppNode)->val)
- {
- pNode->next = *ppNode;
- (*ppNode) = pNode;
- return;
- }
- cur = *ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode<T>** ppNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(NULL == ppNode || NULL == *ppNode)
- return;
- cur = (*ppNode)->next;
- (*ppNode)->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- /*
- //版本2:指针的引用
- private:
- //对于待插入的节点,选择合适的位置插入
- void _list_insert_sort(ListNode<T>*& ppNode, ListNode<T> *pNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(pNode->val < ppNode->val)
- {
- pNode->next = ppNode;
- ppNode = pNode;
- return;
- }
- cur = ppNode;
- while(cur != NULL)
- {
- if(pNode->val < cur->val)
- break;
- prev = cur;
- cur = cur->next;
- }
- pNode->next = cur;//或pNode->next = prev->next
- prev->next =pNode;
- return;
- }
- public:
- //首先遍历节点,一边是排序好的节点,一边是待排序的节点
- void list_insert_sort(ListNode<T>*& ppNode)
- {
- ListNode<T>* prev = NULL;
- ListNode<T>* cur = NULL;
- if(NULL == ppNode)
- return;
- cur = ppNode->next;
- ppNode->next = NULL;
- while(cur != NULL)
- {
- prev = cur;
- cur = cur->next;
- _list_insert_sort(ppNode,prev);
- }
- }
- */
- };
- //链表归并排序
- template <typename T>
- class List_merge_sort
- {
- private:
- //合并两端链表
- //因为可能在头结点之前插入数据,故为ListNode<T>** list1
- ListNode<T>* list_merge(ListNode<T>* list1, ListNode<T>* list2)
- {
- if(NULL == list1)
- return list2;
- else if(NULL == list2)
- return list1;
- ListNode<T>* dummy = new ListNode<T>(-);//辅助头结点
- dummy->next = list1;
- ListNode<T>* list1_cur = dummy;
- ListNode<T>* list2_cur = list2;
- while(list1_cur->next != NULL && list2_cur != NULL)
- {
- //cout<< list1_cur->next->val <<"==="<< list2_cur->val<<endl;
- //把后面一段list2更小的元素插入前面一段list1中
- if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
- {
- list2 = list2->next;
- list2_cur->next = list1_cur->next;
- list1_cur->next = list2_cur;
- list1_cur = list2_cur;
- list2_cur = list2;
- }
- else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
- list1_cur = list1_cur->next;
- }
- //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
- if(NULL == list1_cur->next)
- list1_cur->next = list2_cur;
- ListNode<T>* pHead = dummy->next;
- delete dummy;//释放dummy
- return pHead;//返回头结点
- }
- //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode<T>** pHead)
- ListNode<T>* _list_merge_sort(ListNode<T>** pHead)
- {
- if(NULL == *pHead || NULL == (*pHead)->next)
- return *pHead;
- ListNode<T>* pSlow = *pHead;
- ListNode<T>* pFast = *pHead;
- while(pFast->next !=NULL && pFast->next->next !=NULL)
- {
- pSlow = pSlow->next;
- pFast = pFast->next->next;
- }
- ListNode<T>* pLeftHead = *pHead;
- ListNode<T>* pRightHead = pSlow->next;
- pSlow->next = NULL;//左半链表尾节点的next赋空值
- /*pLeftHead = */_list_merge_sort(&pLeftHead);
- /*pRightHead = */_list_merge_sort(&pRightHead);
- //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部
- //的的next可能已经变了,因此他们可能伸长或缩短
- *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
- return *pHead;
- }
- public:
- //归并排序入口,去掉了返回值,不包装这一层也行
- void list_merge_sort(ListNode<T>** pHead)
- {
- _list_merge_sort(pHead);//注意这里传入的是地址
- }
- };
- //链表快速排序(测试样例)
- void test_list_qsort()
- {
- //创建结点
- ListNode<double>* pNode1 = create_list_node<double>(1.8);
- ListNode<double>* pNode2 = create_list_node<double>(7.3);
- ListNode<double>* pNode3 = create_list_node<double>(2.6);
- ListNode<double>* pNode4 = create_list_node<double>();
- ListNode<double>* pNode5 = create_list_node<double>(-5.8);
- ListNode<double>* pNode6 = create_list_node<double>(99.5);
- ListNode<double>* pNode7 = create_list_node<double>();
- ListNode<double>* pNode8 = create_list_node<double>();
- ListNode<double>* pNode9 = create_list_node<double>(-);
- //连接结点
- connect_list_node(pNode1,pNode2);
- connect_list_node(pNode2,pNode3);
- connect_list_node(pNode3,pNode4);
- connect_list_node(pNode4,pNode5);
- connect_list_node(pNode5,pNode6);
- connect_list_node(pNode6,pNode7);
- connect_list_node(pNode7,pNode8);
- connect_list_node(pNode8,pNode9);
- //打印链表
- cout<<"原链表: ";print_list(pNode1);
- //快速排序
- List_qsort<double> test_qsort;
- test_qsort.list_qsort(pNode1);//传值
- //test_qsort.list_qsort(&pNode1);//传指针
- //test_qsort.list_qsort(pNode1);//传引用
- cout<<"排序后: ";print_list(pNode1);
- /**********销毁链表(我们一般用到的方法,会出现空悬指针)********************/
- // destory_list(&pNode1);
- // //注意,释放链表后,头结点为NULL,其余的虽然释放了,但地址还在,因此成为空悬指针,需要进一步释放
- // //从这个角度来看,还不如写个函数释放每个节点,因此写了一个
- // if(pNode1)
- // print_list(pNode1);
- // else
- // cout<<"-1"<<endl;
- /***********************************************************************/
- /****************销毁链表(逐个销毁,不会出现空悬指针)*********************/
- destory_Node(&pNode1);
- destory_Node(&pNode2);
- destory_Node(&pNode3);
- destory_Node(&pNode4);
- destory_Node(&pNode5);
- destory_Node(&pNode6);
- destory_Node(&pNode7);
- destory_Node(&pNode8);
- destory_Node(&pNode9);
- // if(pNode1)
- // print_list(pNode1);
- // else
- // cout<<"-1"<<endl;
- /***********************************************************************/
- }
- //链表插入排序(测试样例)
- void test_list_insertion_sort()
- {
- //创建结点
- ListNode<double>* pNode1 = create_list_node<double>(1.8);
- ListNode<double>* pNode2 = create_list_node<double>(7.3);
- ListNode<double>* pNode3 = create_list_node<double>(2.6);
- ListNode<double>* pNode4 = create_list_node<double>();
- ListNode<double>* pNode5 = create_list_node<double>(-5.8);
- ListNode<double>* pNode6 = create_list_node<double>(99.5);
- ListNode<double>* pNode7 = create_list_node<double>();
- ListNode<double>* pNode8 = create_list_node<double>();
- ListNode<double>* pNode9 = create_list_node<double>(-);
- //连接结点
- connect_list_node(pNode1,pNode2);
- connect_list_node(pNode2,pNode3);
- connect_list_node(pNode3,pNode4);
- connect_list_node(pNode4,pNode5);
- connect_list_node(pNode5,pNode6);
- connect_list_node(pNode6,pNode7);
- connect_list_node(pNode7,pNode8);
- connect_list_node(pNode8,pNode9);
- //打印链表
- cout<<"原链表: ";print_list(pNode1);
- //插入排序
- List_insertion_sort<double> test_insertion_sort;
- test_insertion_sort.list_insert_sort(&pNode1);//传指针
- //test_insertion_sort.list_insert_sort(pNode1);//传引用
- cout<<"排序后: ";print_list(pNode1);
- }
- //链表归并排序(测试样例)
- void test_list_merge_sort()
- {
- //创建结点
- ListNode<double>* pNode1 = create_list_node<double>(1.8);
- ListNode<double>* pNode2 = create_list_node<double>(7.3);
- ListNode<double>* pNode3 = create_list_node<double>(2.6);
- ListNode<double>* pNode4 = create_list_node<double>();
- ListNode<double>* pNode5 = create_list_node<double>(-5.8);
- ListNode<double>* pNode6 = create_list_node<double>(99.5);
- ListNode<double>* pNode7 = create_list_node<double>();
- ListNode<double>* pNode8 = create_list_node<double>();
- ListNode<double>* pNode9 = create_list_node<double>(-);
- //连接结点
- connect_list_node(pNode1,pNode2);
- connect_list_node(pNode2,pNode3);
- connect_list_node(pNode3,pNode4);
- connect_list_node(pNode4,pNode5);
- connect_list_node(pNode5,pNode6);
- connect_list_node(pNode6,pNode7);
- connect_list_node(pNode7,pNode8);
- connect_list_node(pNode8,pNode9);
- //打印链表
- cout<<"原链表: ";print_list(pNode1);
- //归并排序
- List_merge_sort<double> test_merge_sort;
- //ListNode<double>* p=test_merge_sort.list_merge_sort(&pNode1);//传指针
- test_merge_sort.list_merge_sort(&pNode1);
- cout<<"排序后: ";print_list(pNode1);
- }
- int main()
- {
- cout<<"测试程序:"<<endl<<endl;
- cout<<"链表快速排序:"<<endl;
- test_list_qsort();
- cout<<endl;
- cout<<"链表插入排序:"<<endl;
- test_list_insertion_sort();
- cout<<endl;
- cout<<"链表归并排序:"<<endl;
- test_list_merge_sort();
- cout<<endl;
- return ;
- }
总结
链表的操作都基于指针,我们可以通过编写其各种排序代码练习对指针的操作,如指针的指针,指针的引用等。
另外,我这里只是演示了三种排序方法,如果有错误敬请指正。大家可试试编写几种其他的排序方法。
参考文章
- 单链表排序----快排 & 归并排序http://blog.csdn.net/u012658346/article/details/51141288
- 深入单链表的快速排序详解 http://www.jb51.net/article/37300.htm
- 一步一步写算法(之链表排序)http://blog.csdn.net/feixiaoxing/article/details/6905260/
- 算法题——单链表的归并排序http://www.cnblogs.com/qieerbushejinshikelou/archive/2014/08/17/3917302.html
在此对以上文章作者表示感谢。欢迎交流。
【模板小程序】链表排序(qsort/insert_sort/merge_sort)的更多相关文章
- 模板小程序】求小于等于N范围内的质数
xiaoxi666 联系邮箱: xiaoxi666swap@163.com 博客园 首页 新随笔 联系 订阅 管理 [模板小程序]求小于等于N范围内的质数 1 //筛法求N以内的素数(普通法+优化 ...
- 【模板小程序】求小于等于N范围内的质数
//筛法求N以内的素数(普通法+优化),N>=2 #include <iostream> #include <cmath> #include <vector> ...
- 【模板小程序】求M~N范围内的质数个数
/* 本程序说明: [编程题] 求素数 时间限制:2秒 空间限制:32768K 输入M.N,1 < M < N < 1000000,求区间[M,N]内的所有素数的个数.素数定义:除了 ...
- 【模板小程序】循环方阵构造(仿《剑指offer》循环矩阵打印)
/* 本程序说明: 输入:方阵大小n,输出:n*n的旋转方阵 举例: 当n=2时,输出: 1 2 4 3 当n=4时,输出: 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 ...
- 【模板小程序】求第n个fibonacci数
//fibonacci,find the nth num. 1 1 2 3 5 8... #include <iostream> using namespace std; int fib( ...
- 【模板小程序】求第n个质数
#include <iostream> #include <vector> using namespace std; int nth_prime(int n) { vector ...
- 【模板小程序】任意长度非负十进制数转化为二进制(java实现)
妈妈再也不用担心十进制数过大了233(注意只支持非负数) import com.google.common.base.Strings; import java.math.BigInteger; imp ...
- 微信小程序学习指南
作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- “我的小程序”来了 新版微信v6.7.1下拉就能找到
今天iOS版微信迎来v6.7.1正式版发布,本次升级主要是可以把常用的小程序添加到“我的小程序”.近期版本微信可以直接浏览订阅号的消息,扫一扫可拍照翻译整页中英文,浏览的文章支持缩小为浮窗.两大更新如 ...
随机推荐
- JavaScript事件与例子
事件,就是预先设置好的一段代码,等到用户触发的时候执行. 一:常见的事件: 1.关于鼠标的事件 onclick 鼠标单击触发 ondblclick 鼠标双击触发 onmouseover 鼠标移上触发 ...
- 【知识整理】这可能是最好的RxJava 2.x 入门教程(二)
这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) GitHub 代码同步更新:https://github.com/nanchen22 ...
- 【Android Developers Training】 6. 配置Action Bar
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- Angular 4 学习笔记 从入门到实战 打造在线竞拍网站 基础知识 快速入门 个人感悟
最近搞到手了一部Angular4的视频教程,这几天正好有时间变学了一下,可以用来做一些前后端分离的网站,也可以直接去打包web app. 环境&版本信息声明 运行ng -v @angular/ ...
- Vijos 1012 清帝之惑之雍正 平面最近点对(分治)
背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...
- VB6之断点续传
闲来无事,研究了下HTTP的断点续传,用VB6写了小Demo. 关于HTTP-Range细节可参考: http://www.w3.org/Protocols/rfc2616/rfc2616.html ...
- Struts2的知识点小总结
strust2是 struts1和webwork的结合 (本质相当于servlet) 核心:拦截器 interceptor action ognl和valuestack 使用struts的准备工作 ...
- java constructor 在构造子类时,一定会调用到父类的构造方法 “ 私有属性被继承了?”问题
” Error:Implicit super constructor Pet() is undefined. Must explicitly invoke another constructor “ ...
- JavaScript+svg绘制的一个动态时钟
结果图: 代码如下: <!DOCTYPE html> <html> <head> <title>动态时钟</title> </head ...
- RecyclerView-------之GridView模式加载更多
随着RecyclerView的出现,Listview.GridView的使用率相对有些减少,废话不多说,先看一下效果: 代码如下: 1.自定义的RecyclerView(根据自己的需要) public ...