左程云新手班第四节

1反转单链表

​
#include<iostream>
using namespace std;
class node{
	public:
		int value;
		node *next;
		node(int data):value(data),next(NULL){};	
};
node *reverseLinkedList(node *head)//返回node*的原因:链表反转后原先的头结点已经不是
//现在的头结点 
{
	node *pre=NULL;
	node *next=NULL;
	while(head!=NULL)
	{
		next=head->next;
		head->next=pre;
		pre=head;
		head=next;
	}
	return pre;
}

​

 2反转双链表

#include<iostream>
using namespace std;
class doublenode{
	public:
	int value;
	doublenode *last;
	doublenode *next;
	doublenode(int data):value(),last(NULL),next(NULL){}
};
doublenode* reverseDoubleList(doublenode *head)
{
	doublenode *pre=NULL;
	doublenode *next=NULL;
	while(head!=NULL)
	{
		next=head->next;
		head->next=pre;
		head->last=next;
		pre=head;
		head=next;
	}
	return pre;
}

3单链表实现栈和队列

#include <iostream>
#include <queue>
#include <stack>
using namespace std;

template <typename V>
class Node {
public:
    V value;
    Node<V>* next;

    Node(V v) : value(v), next(nullptr) {}
};

template <typename V>//用链表实现队列 
class MyQueue {
private:
    Node<V>* head;
    Node<V>* tail;
    int size;

public:
    MyQueue() : head(nullptr), tail(nullptr), size(0) {}//初始时均指向空 

    bool isEmpty() {
        return size == 0;
    }

    int getSize() {
        return size;
    }

    void offer(V value){//向尾部添加一个元素 
        Node<V>* cur = new Node<V>(value);
        if (tail == nullptr) {
            head = cur;
            tail = cur;
        } else {
            tail->next = cur;
            tail = cur;
        }
        size++;
    }

    V poll() {//移除头部元素 
        V ans;
        if (head != nullptr) {
            ans = head->value;
            Node<V>* next = head->next;
            delete head;
            head = next;
            size--;
            if (head == nullptr) {
                tail = nullptr;
            }
        }
        return ans;
    }

    V peek() {//获取队头元素 
        return head != nullptr ? head->value : NULL;
    }
};

template <typename V>
class MyStack {
private:
    Node<V>* head;
    int size;

public:
    MyStack() : head(nullptr), size(0) {}

    bool isEmpty() {
        return size == 0;
    }

    int getSize() {
        return size;
    }

    void push(V value) {
        Node<V>* cur = new Node<V>(value);
        if (head == nullptr) {
            head = cur;
        } else {
            cur->next = head;
            head = cur;
        }
        size++;
    }

    V pop() {
        V ans;
        if (head != nullptr) {
            ans = head->value;
            Node<V>* next = head->next;
            delete head;
            head = next;
            size--;
        }
        return ans;
    }

    V peek() {
        return head != nullptr ? head->value : NULL;
    }
};

4用双链表实现双端队列

#include <iostream>
#include <deque>
#include <cstdlib>

template<typename V>
class Node {
public:
    V value;
    Node<V>* last;
    Node<V>* next;
    Node(V v) : value(v), last(nullptr), next(nullptr) {}
};

template<typename V>
class MyDeque {
private:
    Node<V>* head;
    Node<V>* tail;
    int size;

public:
    MyDeque() : head(nullptr), tail(nullptr), size(0) {}

    bool isEmpty() {
        return size == 0;
    }

    int getSize() {
        return size;
    }

    void pushHead(V value) {//头部加入一个元素 
        Node<V>* cur = new Node<V>(value);
        if (head == nullptr) {
            head = cur;
            tail = cur;
        } else {
            cur->next = head;
            head->last = cur;
            head = cur;
        }
        size++;
    }

    void pushTail(V value) {//尾部插入一个元素 
        Node<V>* cur = new Node<V>(value);
        if (head == nullptr) {
            head = cur;
            tail = cur;
        } else {
            tail->next = cur;
            cur->last = tail;
            tail = cur;
        }
        size++;
    }

    V pollHead() {//获取头部元素并删除 
        V ans = V();
        if (head == nullptr) {
            return ans;
        }
        size--;
        ans = head->value;
        if (head == tail) {
            delete head;
            head = nullptr;
            tail = nullptr;
        } else {
            Node<V>* temp = head;
            head = head->next;
            head->last = nullptr;
            delete temp;
        }
        return ans;
    }

    V pollTail() {//获取尾部元素并删除 
        V ans = V();
        if (head == nullptr) {
            return ans;
        }
        size--;
        ans = tail->value;
        if (head == tail) {
            delete tail;
            head = nullptr;
            tail = nullptr;
        } else {
            Node<V>* temp = tail;
            tail = tail->last;
            tail->next = nullptr;
            delete temp;
        }
        return ans;
    }

    V peekHead() {
        V ans = V();
        if (head != nullptr) {
            ans = head->value;
        }
        return ans;
    }

    V peekTail() {
        V ans = V();
        if (tail != nullptr) {
            ans = tail->value;
        }
        return ans;
    }

    ~MyDeque() {
        while (head != nullptr) {
            Node<V>* temp = head;
            head = head->next;
            delete temp;
        }
    }
};

5  K个节点的组内逆序调整问题:
给定一个单链表的头节点head,和一个正数k
实现k个节点的小组内部逆序,如果最后一组不够k个就不调整
例子: 
调整前:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8,k = 3
调整后:3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7 -> 8

#include<iostream>
struct ListNode{
	int val;
	ListNode* next;
	ListNode(int x):val(x),next(NULL){}
};
ListNode* getKGroupEnd(ListNode* start, int k)//往后移动k个元素找到每个k组的尾巴
{
	while(--k!=0&&start!=NULL)//移动k下且当不够k组时退出
	{
		start=start->next; 
	}
	return start;
} 
void reverse(ListNode* start, ListNode* end)//反转某个片段链表 
{
	end=end->next;//e下一个指针也得调整所以e要往下移动一位
	ListNode* pre = NULL;
    ListNode* cur = start;
    ListNode* next = NULL;
    while (cur != end) {
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }
    start->next=end;//最后头部的要指到end 
}
ListNode* reverseKGroup(ListNode* head, int k)//第一组和后面组反转不一样
//第一组的end反转完后没有前指针,但后面的需要调整前指针 
{
	ListNode* start=head;
	ListNode* end=getKGroupEnd(start,k);
	if(end==NULL)//一组都凑不够
	{
		return head; 
	}
	head=end;//head往后移动
	reverse(start,end);
	ListNode* lastEnd=start;//保存上一个的末尾节点以接到下一个k组
	  while (lastEnd->next != nullptr) {
        start = lastEnd->next;
        end = getKGroupEnd(start, k);
        if (end == nullptr) {
            return head;
        }
        reverse(start, end);
        lastEnd->next = end;
        lastEnd = start;
    }
    return head; 
}

6 两个链表相加问题
给定两个链表的头节点head1和head2,
认为从左到右是某个数字从低位到高位,返回相加之后的链表
例子     4 -> 3 -> 6        2 -> 5 -> 3
返回     6 -> 8 -> 9
解释     634 + 352 = 986

#include <iostream>
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};
int listLength(ListNode* head)//先求出链表长度分出长短链表 
{
    int len=0;
	while(head!=NULL)
	{
		len++;
		head=head->next;
	} 
	return len;
}
ListNode* addTwoNumbers(ListNode* head1, ListNode* head2) 
{
	int len1=listLength(head1);
	int len2=listLength(head2);
	ListNode *l=len1>=len2?head1:head2;//长链表的头部,最后要返回长链表头 
	ListNode *s=l==head1?head2:head1;//转到另一个链表头部
	ListNode *curL=l;
	ListNode *curS=s;
	ListNode *last=curL;//最后如果有进位1就补上 
	int carry=0;//进位数 
	int curNum=0;
	while(curS!=NULL)//先把短链表跑完
	{
	   curNum=curL->val+curS->val+carry;
	   curL->val=curNum%10;
	   carry=curNum/10;
	   last=curL;
	  curL=curL->next;
	  curS=curS->next;
	 }
	 while(curL!=NULL)
	 {
	 	curNum=curL->val+carry;
	 	curL->val=curNum%10;
	 	carry=curNum/10;
	 	last=curL;
	 	curL=curL->next;
	 }
	 if(carry!=0)
	 last->next=new ListNode(1);
	 return l;	 
}

7 两个有序链表的合并
给定两个有序链表的头节点head1和head2,
返回合并之后的大链表,要求依然有序
例子     1 -> 3 -> 3 -> 5 -> 7   2 -> 2 -> 3 -> 3-> 7
返回     1 -> 2 -> 2 -> 3 -> 3 -> 3 -> 3 -> 5 -> 7

#include <iostream>
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};
ListNode* mergeTwoLists(ListNode* head1, ListNode* head2) 
{
	if(head1==NULL||head2==NULL)//两个之内有空链表 
	return head1==NULL?head2:head1;
	ListNode *head=head1->val<=head2->val?head1:head2;//去小头链表的头 
	ListNode *cur1=head->next;
	ListNode *cur2=head==head1?head2:head1; 
	ListNode *pre=head;
	while(cur1!=NULL&&cur2!=NULL)
	{
		if(cur1->val<=cur2->val)
		{
			pre->next=cur1;
			cur1=cur1->next; 
		}
		else 
		{
			pre->next=cur2;
			cur2=cur2->next;
		}
		pre=pre->next;
	 }
	 pre->next=cur1!=NULL?cur1:cur2;//把没结束的链表补到后面 
	 return head; 
}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值