DS:链表操作

本周DS的课后作业,写了没多久
花了比较多的时间找第一题的bug
总结:一定要把思路理清楚再动手写?

合并两个非递减链表为非递增链表

思路非常清晰的一题,先合并为非递减链表,再反转即可
合并时可以想像其过程,要点在每次判断需要合并的个数
反转参考了网络,要记住方法

#include<iostream>
using namespace std;

template<class Type>
class List;
template<class Type>
class Linknode{
    friend class List<Type>;
    public:
        Linknode(){next=NULL;}
        Linknode(const Type &value){
            data=value;
            next=NULL;
        };
    private:
        Type data;
        Linknode<Type> *next;
};
template<class Type>
class List{
    private:
        Linknode<Type> *head;
    public:
        List();
        ~List(){};
        bool create(int n);
        void show();
        Linknode<Type> *order(List a,List b);
        Linknode<Type> *reverse(Linknode<Type> *a);
        int length(List a);
    void show(Linknode<Type> *p);
};

template<class Type>
List<Type>::List()
{
    head=NULL;
 }

template<class Type>
void List<Type>::show(){
    Linknode<Type> *p=head;
    if(head==NULL) cout<<"链表为空"<<endl;
    else {
        for(;p;p=p->next)
        cout<<p->data<<"  ";}
    cout<<endl;
}

template<class Type>
void List<Type>::show(Linknode<Type> *p){
    if(p==NULL) cout<<"链表为空"<<endl;
    else {
        for(;p;p=p->next)
        cout<<p->data<<"  ";}
    cout<<endl;
}

template<class Type>
bool List<Type>::create(int n)
{   int i=0;
    head=new Linknode<Type>(NULL);
    Linknode<Type> *p=head,*q;
    if (n==0) return false;
    for (i=1;i<n;i++)
    {
        cin>>p->data;
        q=new Linknode<Type>(NULL);
        p->next=q;
        p=q;
    }
    cin>>p->data;//last node
    p->next=NULL;
    return true;
}

template<class Type>
Linknode<Type>* List<Type>::order(List a,List b)
{   int i=0;
    Linknode<Type> *pa,*pan,*pb,*pbn;
    if(a.head->data<=b.head->data) {i=1;pa=a.head;pb=b.head;}
    else {pa=b.head;pb=a.head;}
    pan=pa->next;pbn=pb->next;
    while(pan&&pbn)
    {
        if(pa->data<=pb->data) 
		{while(pan&&pbn&&(pan->data<=pb->data))
        {pa=pa->next;pan=pan->next;}
        pa->next=pb;pa=pan;pan=(pa)?pa->next:NULL;continue;}
        if(pb->data<=pa->data)
        {while(pbn&&pan&&(pbn->data<=pa->data))
        {pb=pb->next;pbn=pbn->next;}
        pb->next=pa;pb=pbn;pbn=(pb)?pb->next:NULL;}
    }
    if(pa&&!pan&&pb) {if(pb->data>=pa->data) {pa->next=pb;return i?a.head:b.head;}
	else {while(pbn&&(pbn->data<=pa->data)) 
	{pb=pb->next;pbn=pbn->next;}
	pb->next=pa;pa->next=pbn; return i?a.head:b.head;}}
    if(pb&&!pbn&&pa){
	while(pan&&(pan->data<=pb->data)) 
	{pa=pa->next;pan=pan->next;}
	pa->next=pb;pb->next=pan; return i?a.head:b.head;}
	if(!pan&&!pbn) pa->next=pb;
    return i?a.head:b.head;
}

template<class Type>
int List<Type>::length(List a)
{   Linknode<Type> *p=a.head;int i=0;
    if(p==NULL) return 0;
    while(!p){p=p->next;i++;}
    return i;
}

template<class Type>
Linknode<Type>* List<Type>::reverse(Linknode<Type> *a)
{
    Linknode<Type> *pnow,*pnext,*ppre;
    ppre=a;pnow=a->next;pnext=pnow->next;
    pnow->next=ppre;ppre->next=NULL;//first reverse
    ppre=pnow;pnow=pnext;pnext=(pnow)?pnow->next:NULL;
    while(pnow)
    {
        pnow->next=ppre;
        ppre=pnow;pnow=pnext;
        pnext=(pnow)?pnow->next:NULL;
    }
    return ppre;
}

int main()
{   int n1=0,n2=0;
    Linknode<int> *h;
    List<int> a,b;
    cout<<"输入第一个非递减链表的元素个数:"<<endl;
    cin>>n1;
    cout<<"输入"<<n1<<"个整数:"<<endl;
    a.create(n1);
    cin.sync();
    cout<<"输入第二个非递减链表的元素个数:"<<endl;
    cin>>n2;
    cout<<"输入"<<n2<<"个整数:"<<endl;
    b.create(n2);
    cout<<"================================================"<<endl;
    cout<<endl<<"第一个非递减链表:"<<endl;
    a.show();
    cout<<endl<<"第二个非递减链表:"<<endl;
    b.show();
    h=a.order(a,b);
    h=a.reverse(h);
    cout<<endl<<"输出排序后非递增链表:"<<endl;
    a.show(h);
}
判断链表中是否有环

有环返回环的第一个结点
学习了Floyd环的思路,快慢指针相遇的情况
比较难想的思路,但是适用情况不多

#include<iostream>
using namespace std;

template<class Type>
class List;
template<class Type>
class Linknode{
    friend class List<Type>;
    public:
        Linknode(){next=NULL;}
        Linknode(const Type &value){
            data=value;
            next=NULL;
        };
    private:
        Type data;
        Linknode<Type> *next;
};
template<class Type>
class List{
    private:
        Linknode<Type> *head;
    public:
        List();
        ~List(){};
        bool create(int n);
        void show();
        Linknode<Type> *loop(int n);
};

template<class Type>
List<Type>::List()
{
    head=NULL;
 }

template<class Type>
void List<Type>::show(){
    Linknode<Type> *p=head;
    if(head==NULL) cout<<"链表为空"<<endl;
    else {
        for(;p;p=p->next)
        cout<<p->data<<"  ";}
    cout<<endl;
}

template<class Type>
bool List<Type>::create(int n)
{   int i=0,x=0;
    char answer;
    head=new Linknode<Type>(NULL);
    Linknode<Type> *p=head,*q;
    if (n==0) return false;
    while(1){
	cout<<"是否建立有环链表?(Y/N)"<<endl;
    cin>>answer;
	if(answer=='N'||answer=='Y') break;
	else cout<<"选择失败,重新输入"<<endl;} 
	cout<<"输入"<<n<<"个整数:"<<endl;
    for (i=1;i<n;i++)
    {
        cin>>p->data;
        q=new Linknode<Type>(NULL);
        p->next=q;
        p=q;
    }
    cin>>p->data;//last node
    if(answer=='Y'){cout<<"输入入环节点的序号:"<<endl;
	cin>>x;q=head;i=1;
	while(i<x) {q=q->next;i++;}
	p->next=q;}
	else  p->next=NULL;
    return true;
}
template<class Type>
Linknode<Type>* List<Type>::loop(int n)
{
    Linknode<Type> *fast=head,*slow=head; 
    if(n==0) {cout<<"链表为空"<<endl; return NULL;}
    while(fast&&slow)
    {fast=fast->next;fast=(fast)?fast->next:NULL;
    slow=slow->next;
	if(fast==slow) 
	{cout<<"链表有环"<<endl;
	fast=head;while(fast!=slow) {fast=fast->next;slow=slow->next;}
	cout<<"环的第一个节点:"<<fast->data<<endl;return fast;}
	if(!fast) {cout<<"链表无环"<<endl;return head;}
	} 
}

int main()
{
    int n1=0,n2=0;
    List<int> a;
    cout<<"输入链表的元素个数:"<<endl;
    cin>>n1;
    a.create(n1);
    cout<<"================================================"<<endl;
    a.loop(n1);
 } 

对链表的模版类定义熟悉了很多,思路也是理清了才写的
但是对细节的思考仍然不够

  • 要分类每种情况,想好解决思路
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值