标签:剑指offer
关于链表
链表是一种动态的数据结构,因为在创建链表时无需知道链表的长度,当插入一个节点时,只需要为新的节点分配内存,其空间效率和数组相比要高,但是每次都要创建空间所以时间不是很高
单向链表定义节点
struct ListNode { int m_value; ListNode* m_pNext; };
在链表后面添加节点
void AddToTail(ListNode** pHead,int value)//时间效率O(N) { ListNode* pnewNode=new ListNode();//创建新结点 pnewNode->m_value=value; pnewNode->m_pNext=NULL; if(pHead==NULL)//当头结点为空 { pHead=pnewNode; } else//不为空 { ListNode*pNode=*pHead; while(pNode->m_next!=NULL)//遍历找到最后一个节点 { pNode=pNode->m_next; } pNode->m_next=pnewNode; } }
删除其中某节点
void RemoveNode(ListNode**pHead, int value) { if (pHead == NULL||*pHead==NULL)//头结点为空 return; ListNode*pDelete = NULL; if ((*pHead)->m_value == value) { pDelete = *pHead; *pHead = (*pHead)->m_pNext; } else { ListNode*pNode = *pHead; //遍历查找要删除结点的前一个结点 while (pNode->m_pNext!=NULL &&pNode->m_pNext-> m_value != value) { pNode = pNode->m_pNext; } pDelete = pNode->m_pNext; pNode->m_pNext = pDelete->m_pNext; if (pDelete != NULL) { delete pDelete; pDelete = NULL; } }
题目:
输入一个链表头结点,从头到尾反过来打印这个结点值(不改变结点结构)
程序1.0
若链表为空直接返回链表,若只有一个节点,打印此结点;若有多个结点,设置一个计数器,先、遍历结点统计结点个数,再循环结点数次,在这个循环里再依次找到倒数第一个、倒数第二个、倒数第N个节点
void PrintListReverse(ListNode*pHead)//时间复杂度O(N^2) { while (pHead == NULL)//没有结点 return; if (pHead->m_pNext == NULL)//一个节点 { cout << pHead->m_value; return; } ListNode*pNode = pHead; int count =1; while (pNode->m_pNext != NULL) { count++; pNode = pNode->m_pNext; } while (count != 0) { for (int i = 1; i < count; i++) { pNode = pNode->m_pNext;//找到倒数第N个节点的前一个结点 } cout << pNode->m_value << "->"; count--; } }
程序2.0
上面用循环实现,过于复杂且效率不高,所以第二次使用栈来完成,栈有“先入后出”的特性,所以用栈来实现更为方便,没遇到一个不为空的结点就把它放到栈中
void PrintListReverse(ListNode*pHead)//时间复杂度O(N) { stack<ListNode*> s1; ListNode*pNode = pHead; while (pNode->m_pNext != NULL) { s1.push(pNode); pNode = pNode->m_pNext; } while (!s1.empty()) { cout << s1.top()->m_value << "->"; s1.pop(); } }
程序3.0
我们知道递归的本质就是栈,所以我们也可以用栈来实现它,先递归后面的结点,一直递归到没有结点,再输出该结点
void PrintListReverse(ListNode*pHead) { if (pHead != NULL) { if (pHead->m_pNext != NULL)//递归停止条件 { PrintListReverse(pHead->m_pNext); } cout << pHead->m_value << "->"; } }
递归写法虽然看起来要简洁的多,但是若结点超级长则会导致函数调用栈溢出,所以在实现是最好使用显示调用栈的方式来实现
本文出自 “无以伦比的暖阳” 博客,请务必保留此出处http://10797127.blog.51cto.com/10787127/1771262
标签:剑指offer
原文地址:http://10797127.blog.51cto.com/10787127/1771262