标签:blog http io os 数据 sp div c on
#include<iostream> using namespace std; struct ListNode { int m_nKey; ListNode * m_pNext; }; //-------------_创建链表------------- ListNode* create_node(int value) { ListNode *pHead=new ListNode; pHead->m_nKey=value; pHead->m_pNext=NULL; return pHead; } //-------------_删除链表------------- void delete_all1(ListNode *pHead) //_注意,测试一级指针 { if(pHead==NULL) return; ListNode *pNext=pHead->m_pNext; delete pHead;pHead=NULL; //_不行,这里可以将链表头节点删除,但是头结点的地址无法置零 delete_all1(pNext); } void delete_all(ListNode **pHead) { if(NULL==pHead||*pHead==NULL) return; ListNode *temp=(*pHead)->m_pNext; delete (*pHead);*pHead=NULL; delete_all(&temp); } //-------------_尾部添加节点------------- void addtotail(ListNode **pHead,int value) { ListNode *pNew=new ListNode; pNew->m_nKey=value; pNew->m_pNext=NULL; if(pHead==NULL||*pHead==NULL) { *pHead=pNew; return; } ListNode *pTemp=*pHead; while(pTemp->m_pNext) { pTemp=pTemp->m_pNext; } pTemp->m_pNext=pNew; } //-------------_输出节点值------------- void printnode(const ListNode *pHead) { if(pHead) { // const ListNode *pTemp=pHead; // // cout<<pTemp->m_nKey<<‘\t‘; // while(pTemp->m_pNext) // { // pTemp=pTemp->m_pNext; // cout<<pTemp->m_nKey<<‘\t‘; // } // cout<<endl; //--递归-- cout<<pHead->m_nKey<<‘\t‘; printnode(pHead->m_pNext); } } //-------------_插入节点------------- //-------------_删除节点------------- //-------------_O(1)时间删除链表节点------------- //http://vicki007.blog.163.com/blog/static/24505385201142574955729/ /*传统的做法是,从头结点开始,一直找到要删除结点的前趋结点,然后前趋结点的next指针直接指向要删除结点的后继,再free掉要删除的结点就OK了。当然,这个方法的时间复杂度是O(n)。 要在O(1)时间内删除某个结点,所以不能用传统的做法从头结点开始遍历链表找到要删除结点的前趋,而从要删除的结点出发也找不到其自身的前趋,这样要改变一种思路,就是不找前趋! 具体做法是这样的,把头结点的数据直接copy到要删除的结点处,然后头指针向后移动一个结点,再free掉原来的头指针指向的结点,这样等于把要删除的结点删除了。
当链表只有一个结点或者要删除的结点是头结点或尾结点时,这种方法也是成立的,所以不需要做特殊的处理。*/ void O1deletenode1(ListNode **pHead, ListNode *pToBeDeleted) { if(pHead==NULL||pToBeDeleted==NULL) return; (*pHead)->m_nKey=pToBeDeleted->m_nKey; (*pHead)=(*pHead)->m_pNext; delete *pHead,*pHead=NULL; } /*另外,原文中思路有一点不一样,原文作者还是想找到前趋,然后再删除结点。他的做法是,把要删除结点的后继结点的数据copy到要删除结点中,则后继结点就成了要删除的结点了,
那么要删除的结点就变成真正要删除结点的前趋了,然后完成删除。不过这种思路要考虑到待删除结点是尾结点的特殊情况,因为尾结点是没有后继的。 两种方法比较起来,我觉得第一种是比较方便的,但是第二种方法可以保证原来链表的数据排序(如果需要的话)。各有好处吧*/ void O1deletenode2(ListNode **pHead, ListNode *pToBeDeleted) { ; } //-------------_反向输出链表------------- void PrintListReversingly(ListNode *pHead) { if(pHead==NULL) return; PrintListReversingly(pHead->m_pNext); //_递归不适用于链表很长的情况 cout<<pHead->m_nKey<<‘\t‘; } //-------------_反转链表--------------- //最直接的方法 void ReverseList(ListNode **pHead) { if(pHead==NULL||(*pHead)->m_pNext==NULL) return; ListNode *pPre=(*pHead),*pPos=(*pHead)->m_pNext,*pTemp; pPre->m_pNext=NULL; while(pPos) { pTemp=pPos->m_pNext; pPos->m_pNext=pPre; pPre=pPos; pPos=pTemp; } *pHead=pPre; } //_借助递归,每次递归,将当前节点next指向前一个节点,在最后一个节点时给newHead赋值即可 void ReverseList1(ListNode *pHead,ListNode *pre,ListNode *&newHead) { if(!pHead) return; if(!pHead->m_pNext) { pHead->m_pNext=pre; newHead=pHead; return; } ListNode*tmp=pHead->m_pNext; pHead->m_pNext=pre; ReverseList1(tmp,pHead,newHead); } //借助堆栈 void ReverseList2(ListNode **pHead) { ; } void main() { ListNode *pHead=create_node(1); addtotail(&pHead,2); addtotail(&pHead,3); printnode(pHead); cout<<endl; //delete_all(&pHead); //PrintListReversingly(pHead); //ReverseList(&pHead); ListNode *newHead=0; ReverseList1(pHead,NULL,newHead); printnode(newHead); }
标签:blog http io os 数据 sp div c on
原文地址:http://www.cnblogs.com/shirishiyue/p/4009489.html