链表系列之单链表常见面试题
2014-07-24 15:45
232 查看
创建单链表
1、从一个单链表中返回倒数第n个元素
维护两个指针,保持两个指针距离为n,当后面的指针为NULL时,前面的指针即为所求
实现:
2、给出单链表的头指针和一个结点指针,在O(1)时间删除该结点。
把下一个节点的data复制到需要删除的节点覆盖原来的内容,再把下一个节点删除,最后将该节点的next指针指向下下个节点。有两个特殊情况需要单独处理:要删除节点位于链表的尾部;链表只有一个节点。
实现
3、单链表逆置
3.1递归实现:
3.2非递归实现
4、从尾到头打印链表,要求不改变链表结构
4.1、借助栈来实现
4.2由于递归本质就是栈结构,因此也可以用递归实现
5、使用单链表实现大数的加法
typedef struct node { int data; node *next; }Node, *LinkList; //建立链表 Node* createList1(const int a[], int n) { Node *head, *endPtr; head = endPtr = NULL; for(int i=0;i<n;i++) { Node *temp = new Node; temp->data = a[i]; temp->next = NULL; if(i==0) { head = endPtr = temp; // endPtr->next = NULL; } else { endPtr->next = temp; endPtr = temp; } } return head; } /*建立链表2*/ Node* createList2(int a[],int n) { Node *ListHead = new Node; ListHead->data = a[0]; ListHead->next = NULL; for(int i=n-1;i>0;i--) { Node *tmp = new Node; tmp->data = a[i]; tmp->next = ListHead->next; ListHead->next = tmp; } return ListHead; }
1、从一个单链表中返回倒数第n个元素
维护两个指针,保持两个指针距离为n,当后面的指针为NULL时,前面的指针即为所求
实现:
Node *findNthToLast(Node *head, int n) { Node *ptr1 = head, *ptr2 = head; if(head==NULL) //如果链表为空 return NULL; //保证ptr2与ptr1间隔n-1 if(n<=0) return NULL; else { for(int i=1;i<=n-1;i++) { ptr2 = ptr2->next; if(ptr2==NULL) //如果链表长度小于n return NULL; } } while(ptr2->next!=NULL) { ptr1 = ptr1->next; ptr2 = ptr2->next; } return ptr1; }
2、给出单链表的头指针和一个结点指针,在O(1)时间删除该结点。
把下一个节点的data复制到需要删除的节点覆盖原来的内容,再把下一个节点删除,最后将该节点的next指针指向下下个节点。有两个特殊情况需要单独处理:要删除节点位于链表的尾部;链表只有一个节点。
实现
bool deleteNode(Node *head,Node *node) { if(head==NULL) return false; //要删除节点不是尾节点 if(node->next!=NULL) { Node *tmpPtr = node->next; node->data = tmpPtr->data; node->next = tmpPtr->next; delete tmpPtr; } else { if(head==node) //链表只有一个节点 { delete node; head = NULL; } else //删除节点为尾节点 { Node *tmp = head; while(tmp->next!=node) { tmp = tmp->next; } tmp->next = NULL; delete node; } } return true; }
3、单链表逆置
3.1递归实现:
void reverse(Node *pCur,LinkList &ListHead) { if(NULL==pCur||NULL==pCur->next) { ListHead = pCur; } else { Node *pNext = pCur->next; //保存后继节点的指针 reverse(pNext,ListHead); pNext->next = pCur; pCur->next = NULL; } }
3.2非递归实现
void reverseList(LinkList &head) { if(head==NULL||head->next==NULL) //边界检查 return NULL; Node *pPre = head; //用来指向前驱节点 Node *pCur = pPre->next; //用来指向当前节点 Node *pNext = NULL; //用来指向后继节点 while(pCur!=NULL) { pNext = pCur->next; //保存后继节点的指针 pCur->next = pPre; //将当前节点的指针域指向前驱节点 pPre = pCur; pCur = pNext; } head->next = NULL; head = pPre; //新的头节点 }
4、从尾到头打印链表,要求不改变链表结构
4.1、借助栈来实现
void PrintListReversing(LinkList pHead) { stack<Node*> nodes; Node* pNode = pHead; if(pNode==NULL) return; while(pNode!=NULL) //将节点依次入栈 { nodes.push(pNode); pNode = pNode->next; } while(!nodes.empty()) //出栈 { pNode = nodes.top(); cout<<pNode->data<<endl; nodes.pop(); } }
4.2由于递归本质就是栈结构,因此也可以用递归实现
void PrintListReversing2(Node* pHead) { if(pHead==NULL) return; if(pHead!=NULL) { if(pHead->next!=NULL) { PrintListReversing2(pHead->next); } cout<<pHead->data<<endl; } }
5、使用单链表实现大数的加法
/*有两个由单链表表示的数。每个结点代表其中的一位数字。 数字的存储是逆序的, 也就是说个位位于链表的表头。 写一函数使这两个数相加并返回结果,结果也由链表表示。*/ //eg. Input:(3->9->6), (4->7->8->3) // Output:(7->6->5->4) Node *ListAdd(Node* L1, Node* L2) { if(L1==NULL) return L2; if(L2==NULL) return L1; Node *ptr1 = L1, *ptr2 = L2, *ResultPtr=NULL, *TmpPtr=NULL; int carry = 0; Node *p_node = new Node(); p_node->data = (L1->data+L2->data)%10; p_node->next = NULL; carry = (L1->data+L2->data)/10; ResultPtr = TmpPtr = p_node; TmpPtr->next = NULL; L1 = L1->next; L2 = L2->next; while(L1 && L2) { Node *pNode = new Node(); TmpPtr->next = pNode; int tmp = L1->data+L2->data+carry; carry = tmp/10; pNode->data = tmp%10; pNode->next = NULL; TmpPtr = TmpPtr->next; L1 = L1->next; L2 = L2->next; } while(L1) { Node *pNode = new Node(); TmpPtr->next = pNode; int tmp = L1->data+carry; carry = tmp/10; pNode->data = tmp%10; pNode->next = NULL; TmpPtr = TmpPtr->next; L1 = L1->next; } while(L2) { Node *pNode = new Node(); TmpPtr->next = pNode; int tmp = L2->data+carry; carry = tmp/10; pNode->data = tmp%10; pNode->next = NULL; TmpPtr = TmpPtr->next; L2 = L2->next; } if(carry) { Node *pNode = new Node(); TmpPtr->next = pNode; pNode->data = carry; pNode->next = NULL; } return ResultPtr; }
相关文章推荐
- [分类整理II]微软等100题系列V0.1版:链表面试题集锦
- [分类整理II]微软等100题系列V0.1版:链表面试题集锦
- 单链表常见面试题及答案
- 常见链表面试题的总结
- 链表有关的常见面试题
- 常见C语言面试题之九:链表逆序
- 链表常见面试题二:约瑟夫环
- C语言单链表常见操作系列
- 链表常见面试题
- 常见的链表面试题大汇总:
- [分类整理II]微软等100题系列V0.1版:链表面试题集锦
- 常见链表面试题
- 微软面试题系列(一):把二元查找树转变成排序的双向链表
- 常见笔试面试题:实现一个递增排序的单链表
- 链表常见面试题
- [分类整理II]微软等100题系列V0.1版:链表面试题集锦
- 常见链表面试题
- 单链表常见面试题
- 链表常见面试题
- 链表常见面试题一:基本问题