【14 链表中倒数第k个节点】
题目描述
输入一个链表,输出该链表中倒数第k个节点。
思路:
1)如何创建链表:head指向链表头,设置两个指针,p为遍历指针,q为新节点指针,
2)判断链表为空,链表长度少于k个节点的情况
3)倒数第k个节点: 先行指针p先走k-1个指针,指向正序中第k个节点。q指向头节点,p,q同时开始往后遍历,p指向最后一个节点的时候,q所指向的节点就是倒数第k个节点。
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { //寻找倒数 第K个节点
ListNode *p=pListHead,*q=pListHead;
int i=0;
if(pListHead==NULL) // 链表首先判断是否为空
return NULL;
for(i=0;i<k-1;i++)
// 利用两个指针p,q,p指针先遍历k-1个节点(指向第k个节点),q再开始遍历p到最后一个节点的位置,q指向倒数k个节点
{
if(p->next!=NULL)
p = p->next;
else
return NULL;
}
while(p->next!=NULL)
{
p = p->next;
q = q->next;
}
return q;
}
【15 反转链表】
题目描述
输入一个链表,反转链表后,输出新链表的表头。
思路:
1)反转链表,主要就是将指针的方向进行逆向,要小心保留遍历指针的位置。
ListNode* ReverseList(ListNode* pHead) { //反转链表
ListNode *head=pHead,*q=pHead,*p=pHead;
if(head==NULL||head->next==NULL)
return head;
p = head->next; //遍历指针
q = p;
head->next=NULL; // 头节点为反转链表的尾节点,需要指向NULL
while(q->next!=NULL)
{
p = p->next;
// head 记录反转链表的头部,q指向当前节点,p很重要,指向原链表的下一个位置,要在q->next之前先保留值,因为这边有p->next
// 因此,while条件判断 p->next 或者q->next 为非空,是为了循环体内的 p->next 越界!!!
q->next = head;
head = q;
q = p;
}
//cout<<head->val<<"->"<<q->val<<"->"<<p->val<<endl;
q->next = head;
head = q;
return head;
}
//主函数,主要是链表的创建
int main()
{
ListNode *head=NULL,*p,*q;
int val,i,k;
char c;
p = head;
while((c=cin.get())!='\n') //根据输入值创建链表 节点
{
cin.unget();
cin>>val;
q = (ListNode*)malloc(sizeof(ListNode));
q->val = val;
if(head==NULL)
{
head = q;
//p = head;
}
else
p->next=q;
p = q;
}
p->next = NULL;
p = head;
cin>>k;
cout<<"List:"<<endl;
while(p!=NULL)
{
cout<<p->val<<',';
p=p->next;
}
cout<<endl;
q = FindKthToTail(head,k);
cout<<"FindKthToTail:"<<q->val<<endl;
p = ReverseList(head);
cout<<"ReverseList:"<<endl;
while(p!=NULL)
{
cout<<p->val<<',';
p=p->next;
}
return 0;
}
【16-合并两个排序的链表】
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:
1)判断是否出现某一条链表为空的情况
2)令List1为合并后的链表(p1指向开始节点小的那条链表)
List1:指针p1为待插入的位置,p1->next为比较的节点,p2指向下一个位置
List2:同理,有q1,q2
合并时,比较p1->next与q1指向值大小,小于,则p1++;
大于,修改p1的next指针,指向q1,修改q1的next指针,指向p1->next
3) 判断,List2 是否结束
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode *p1=pHead1,*p2,*q1=pHead2,*q2,*p;
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
if(pHead2->val<pHead1->val)
{
p1 = pHead2; // p1指向最小节点的链表
q1 = pHead1;
}
p = p1;
while(p1->next!=NULL)
{
//cout<<p1->val<<',';
if(p1->next->val<=q1->val)
{
p1 = p1->next;
}
else
{
p2 = p1->next;
q2 = q1->next;
q1->next = p2;
p1->next = q1;
p1 = q1;
q1 = q2;
}
if(q1==NULL) //第二条链表先结束
break;
}
if(q1!=NULL)
{
p1->next=q1;
}
return p;
}