数据结构第二次作业

数据结构第二次作业

p143/27

//反转链表的操作
(a)

template <class T>
void chain<T>::reverse()
{
    if (!head)
        return;
    chainNode<T>* p = nullptr;
    chainNode<T>* q = head;
    chainNode<T>* r = head->next;
    while (r)
    {
        q->next = p;
        p = q;
        q = r;
        r = r->next;
    }
    q->next = p;
    head = q;
}

(b)

*复杂度分析

space complexity:
this program needs three extra store space,so its compelxity is O(1).
需要三个额外的存储空间,所以空间复杂度为O(1)

time complexity:
suppose the length of the list is n,fliping each node needs four operations. So the total times is 4*n,therefore the space complexity is O(n)
假设链表的长度为n,反转每一个节点需要操作四次(根据while循环中的代码),所以反转整个链表的操作次数是4*n,所以空间复杂度是O(n)

(c)
测试见最后整个的代码

p143/28
(a)

template <class T>
void reverse2(chain<T>& A, chain<T>& B)
{

    while (B.gethead())
    {
        B.erase(1);
    }
    chainNode<T>* pp = A.gethead();

    while (pp)
    {
        chainNode<T>* pp3 = new chainNode<T>;
        pp3->data = pp->data;
        pp3->next = B.gethead();
        B.sethead(pp3);
        pp = pp->next;
    }
}

(b)

复杂度分析

根据代码,可知复杂度是O(n)
(c)
最后见总的代码

p143/29
//合并两个链表
(a)

template <class T>
void chain<T>::Alternate(chain<T>& A, chain<T>& B)
{
    while (this->head)
    {
        erase(1);
    }
    //int min = A.size < B.size ? A.size : B.size;

    chainNode<T>* pp1 = A.head;
    chainNode<T>* pp2 = B.head;
    chainNode<T>* pp3;
    int k = 1;
    while (pp1&&pp2)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp1->data;
        pp3->next = nullptr;

        if (k == 1)
        {
            this->head=this->last= pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }

        pp3 = new chainNode<T>;
        pp3->data = pp2->data;
        pp3->next = nullptr;
        last->next = pp3;
        last = last->next;


        pp1 = pp1->next;
        pp2 = pp2->next;
    }
    while (pp1)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp1->data;
        pp3->next = nullptr;

        if (k == 1)
        {
            this->head=this->last = pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }
        pp1 = pp1->next;
    }
    while (pp2)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp2->data;
        pp3->next = nullptr;

        if (k == 1)
        {
            this->head=this->last = pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }
        pp2 = pp2->next;
    }

}

(b)

复杂度分析

space complexity
In this program, we will use four extra variables ,So the space complexity is O(1)
在这个程序中,我们用四个额外的变量,所以程序的空间复杂度为O(1)

time complexity
when deleting the elements in list C,the time complexity is O(1),when traversing the list called A&B,time complexity is O(n)
so the total time comlexity is O(n);
当我们删除链表C中的元素时,时间复杂度是O(n),当我们遍历链表A和B 时,我们需要的时间复杂度仍然是O(n),所以总的时间复杂度是O(n)

(c)
测试见最后给出的总代码

p144/31
(a)

template <class T>
void Merge(chain<T>& A, chain<T>& B,chain<T>& C)
{
    while (C.gethead())
    {
        C.erase(1);
    }
    chainNode<T>* pp1 = A.gethead();
    chainNode<T>* pp2 = A.gethead();
    while (pp1&&pp2)
    {
        if (pp1->data < pp2->data)
        {
            C.append(pp1->data);
            pp1 = pp1->next;
        }
        else
        {
            C.append(pp2->data);
            pp2 = pp2->next;
        }
    }
    while (pp1)
    {
        C.append(pp1->data);
        pp1 = pp1->next;
    }
    while (pp2)
    {
        C.append(pp2->data);
        pp2 = pp2->data;
    }

}

(b)

复杂度分析

空间复杂度为O(n);
时间复杂度为O(n);

p144/32
(a)

template <class T>
void chain<T>::Merge(chain<T>& A, chain<T>& B)
{
    while (this->head)
    {
        erase(1);
    }
    this->head = this->last = nullptr;
    //chainNode<T>* pp = this->head;
    chainNode<T>* pp1 = A.head;
    chainNode<T>* pp2 = B.head;
    chainNode<T>* pp3;
    int k = 1;
    while (pp1&&pp2)
    {
        if (pp1->data < pp2->data)
        {
            pp3 = new chainNode<T>;
            pp3->data = pp1->data;
            pp3->next = nullptr;
            pp1 = pp1->next;
            if (k == 1)
            {
                this->head =this->last= pp3;
                k++;
            }
            else
            {
                last->next = pp3;
                last = last->next;
            }
        }
        else
        {
            pp3 = new chainNode<T>;
            pp3->data = pp2->data;
            pp3->next = nullptr;
            pp2 = pp2->next;
            if (k == 1)
            {
                this->head=this->last = pp3;
                k++;
            }
            last->next = pp3;
            last = last->next;
        }
    }
    while (pp1)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp1->data;
        pp3->next = nullptr;
        pp1 = pp1->next;
        if (k == 1)
        {
            this->head = this->last = pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }
    }
    while (pp2)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp2->data;
        pp3->next = nullptr;
        pp2 = pp2->next;
        if (k == 1)
        {
            this->head = this->last = pp3;
            k++;
        }
        last->next = pp3;
        last = last->next;
    }
}

(b)

复杂度分析

time complexity:
The total time that comparision spends is O(n)
The total time that traversing spends is O(n)
so time complexity is O(n)
比较大小所用时间复杂度是O(n),遍历链表时间复杂度是O(n)
所以总的时间复杂度是O(n)
(c)
测试用例见最后总的代码

p144/33
(a)

template<class T>
void split2(chain<T>&A,chain<T>& B, chain<T>& C)
{
    chainNode<T>* p = A.gethead();
    int k = 1;
    while (p)
    {
        if (k % 2)
        {
            B.append(p->data);
            k++;
        }
        else
        {
            C.append(p->data);
            k++;
        }
        p = p->next;
    }
}

(b)
时间复杂度为O(n)

(c)
测试用例见完整代码实现

p144/34
(a)

template <class T>
void chain<T>::split(chain<T>& B, chain<T>& C)
{
    if (!this->head)
        throw "erroe";
    while (B.head)
    {
        erase(1);
    }
    while (C.head)
    {
        erase(1);
    }
    chainNode<T>* p = this->head;
    chainNode<T>* pp = new chainNode<T>;
    pp->next = nullptr;
    pp->data = p->data;
    B.head = B.last = pp;
    if (head->next)
    {
        p = p->next;
        pp = new chainNode<T>;
        pp->next = nullptr;
        pp->data = p->data;
        C.head = C.last = pp;
        p = p->next;
    }
    int k = 1;
    while (p)
    {
        pp = new chainNode<T>;
        pp->data = p->data;
        pp->next = nullptr;
        if (k % 2)
        {
            B.last->next = pp;
            B.last = B.last->next;
            k++;
        }
        else
        {
            C.last->next = pp;
            C.last = C.last->next;
            k++;
        }
        p = p->next;
    }
}

(b)

复杂度分析

新增变量的个数为常数,所以空间复杂度时O(n),时间复杂度和遍历一遍链表所用的时间是同一量级的,所以时间复杂度是O(n)
(c)
实例见所有代码

完整代码
LinkedList.h文件
#pragma once
#include <iostream>
template <class T>
struct chainNode
{
    //数据成员
    T data;
    chainNode* next;
    //方法成员
    chainNode() {};
    chainNode(const T& element)
    {
        data = element;
    }
    chainNode(const T& element, chainNode<T>* nextp)
    {
        data = element;
        next = nextp;
    }
};

template <class T>
class chain
{
public:
    //构造复制构造析构函数
    chain(int initcapacity = 10);
    chain(const chain<T>&  t);
    ~chain();
    //各种ADT 函数
    bool empty()
    {
        return size == 0;
    }
    int lenght()
    {
        return size;
    }
    T& getIndex(int index)const;
    void erase(int index);
    int indexOf(const T& t)const;
    void insert(int index, const T& t);
    void output(std::ostream& os)const;
    void reverse();
    void split( chain<T>& B, chain<T>& C);
    void append(const T& a)
    {
        chainNode<T>* p = new chainNode<T>;
        p->data = a;
        p->next = nullptr;
        if (head == nullptr)
            head = last = p;
        else
        {
            last->next = p;
            last = last->next;
        }
    }
    chainNode<T>* gethead()
    {
        return head;
    }
    chainNode<T>* getlast()
    {
        return last;
    }
    T& getdata()
    {
        return data;
    }
    void sethead(chainNode<T>* header)
    {

        header->next = head;
        chainNode<T>* pp = head;
        head = header;
        if(!pp)
        delete pp;
    }

    void Alternate(chain<T>& A, chain<T>& B);
    void Merge(chain<T>& A, chain<T>& B);
private:
    int size;
    chainNode<T>* head;
    chainNode<T>* last;
};


//这是一个迭代器,虽然没有什么用没有用!!!!!!
/*
template <class>
class chaininter
{
private:
    chainNode<T>* location;
public:
    T* Init(const chain<T>& c)
    {
        location = c.head;
        if (location)
            return &location;
        return -1;
    }
    T* next()
    {
        if (!location)
            return -1;
        location = location->next;
        if (location)
            return &location;
        return -1;
    }

};
*/


//1构造函数
template <class T>
chain<T>::chain(int initcapacity)
{
    if (initcapacity < 1)
        throw "the lenght is not right";
    head = nullptr;
    size = 0;

}


//2复制构造函数
template <class T>
chain<T>::chain(const chain<T>& t)
{
    size = t.size;
    if (t.head == nullptr)
    {
        head = nullptr;
        return;
    }
    chainNode<T>* p = t.head;
    head = new chainNode<T>;
    head->data = p->data;
    p = p->next;
    chainNode<T>* pp = head;
    while (p != nullptr)
    {
        pp->next = new chainNode<T>
        pp->next->data = p->data;
        p = p->next;
     }
    pp->next = nullptr;
}


//3析构函数
template <class T>
chain<T>::~chain()
{
    while (head!=nullptr)
    {
        chainNode<T>* p = head->next;
        delete head;
        head = p;
    }
}


//4得到索引为index的元素
template <class T>
T&  chain<T>:: getIndex(int index)const
{
    if (index<=0 || index>size)
        throw "there is an error occur";
    chainNode<T>* p = head;
    for (int i = 1; i < index; i++)
        p = p->next;
    return p->data;
}


//5删除链表的某一个元素
template <class T>
void chain<T>::erase(int index)
{
    if (index <= 0 || index > size)
        return;
    if (index == 1)
    {
        chainNode<T>* hh = head;
        head = head->next;
        delete hh;
        size--;
        return;
    }
    chainNode<T>* pp = head;
    for (int i = 1; i < index - 1; i++)
        pp = pp->next;
    chainNode<T>* hh = pp->next;
    pp->next = hh->next;
    delete hh;
    size--;
}

//6找到某个特定元素的次序
template <class T>
int chain<T>::indexOf(const T& t)const
{
    chainNode<T>* hh = head;
    int len = 1;
    while (hh != nullptr&&hh->data != t)
    {   
        hh = hh->next;
        len++;
    }
    if (hh == nullptr)
        return -1;
    return len;
}

//7将t插入到index个元素的后面
template <class T>
void chain<T>::insert(int index, const T& t)
{
    if (index <0 || index > size)
        throw "the index is not correct";
    chainNode<T>* p = new chainNode<T>;
    p->data = t;
    p->next = nullptr;
    if (index == 0)
    {
        p->next = head;
        head = p;

    }
    else
    {
        chainNode<T>* q = head;
        for (int i = 1; i <index; i++)
            q = q->next;
        p->next = q->next;
        q->next = p;
    }
    size++;
}


//输出所有的元素
template <class T>
void chain<T>::output(std::ostream& os)const
{
    for (chainNode<T>* p = head; p != nullptr; p = p->next)
        os << p->data<<" ";
}

//这个是输出所有元素
template <class T>
std::ostream& operator<<(std::ostream& os, chain<T>& aim)
{
    aim.output(os);
    return os;
}


//反转链表的操作
template <class T>
void chain<T>::reverse()
{
    if (!head)
        return;
    chainNode<T>* p = nullptr;
    chainNode<T>* q = head;
    chainNode<T>* r = head->next;
    while (r)
    {
        q->next = p;
        p = q;
        q = r;
        r = r->next;
    }
    q->next = p;
    head = q;
}

template <class T>
void reverse2(chain<T>& A, chain<T>& B)
{

    while (B.gethead())
    {
        B.erase(1);
    }
    chainNode<T>* pp = A.gethead();
    /*
    chainNode<T>* pp2=new chainNode<T>;
    pp2->data = pp->data;
    B.head = pp2;
    B.head->next = nullptr;
    pp = pp->next;
    */
    while (pp)
    {
        chainNode<T>* pp3 = new chainNode<T>;
        pp3->data = pp->data;
        pp3->next = B.gethead();
        B.sethead(pp3);
        pp = pp->next;
    }
}


//这个还是没有完成77
template <class T>
void chain<T>::Alternate(chain<T>& A, chain<T>& B)
{
    while (this->head)
    {
        erase(1);
    }
    //int min = A.size < B.size ? A.size : B.size;

    chainNode<T>* pp1 = A.head;
    chainNode<T>* pp2 = B.head;
    chainNode<T>* pp3;
    int k = 1;
    while (pp1&&pp2)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp1->data;
        pp3->next = nullptr;

        if (k == 1)
        {
            this->head=this->last= pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }

        pp3 = new chainNode<T>;
        pp3->data = pp2->data;
        pp3->next = nullptr;
        last->next = pp3;
        last = last->next;


        pp1 = pp1->next;
        pp2 = pp2->next;
    }
    while (pp1)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp1->data;
        pp3->next = nullptr;

        if (k == 1)
        {
            this->head=this->last = pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }
        pp1 = pp1->next;
    }
    while (pp2)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp2->data;
        pp3->next = nullptr;

        if (k == 1)
        {
            this->head=this->last = pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }
        pp2 = pp2->next;
    }

}
template <class T>
void Merge(chain<T>& A, chain<T>& B,chain<T>& C)
{
    while (C.gethead())
    {
        C.erase(1);
    }
    chainNode<T>* pp1 = A.gethead();
    chainNode<T>* pp2 = A.gethead();
    while (pp1&&pp2)
    {
        if (pp1->data < pp2->data)
        {
            C.append(pp1->data);
            pp1 = pp1->next;
        }
        else
        {
            C.append(pp2->data);
            pp2 = pp2->next;
        }
    }
    while (pp1)
    {
        C.append(pp1->data);
        pp1 = pp1->next;
    }
    while (pp2)
    {
        C.append(pp2->data);
        pp2 = pp2->data;
    }

}


template <class T>
void chain<T>::Merge(chain<T>& A, chain<T>& B)
{
    while (this->head)
    {
        erase(1);
    }
    this->head = this->last = nullptr;
    //chainNode<T>* pp = this->head;
    chainNode<T>* pp1 = A.head;
    chainNode<T>* pp2 = B.head;
    chainNode<T>* pp3;
    int k = 1;
    while (pp1&&pp2)
    {
        if (pp1->data < pp2->data)
        {
            pp3 = new chainNode<T>;
            pp3->data = pp1->data;
            pp3->next = nullptr;
            pp1 = pp1->next;
            if (k == 1)
            {
                this->head =this->last= pp3;
                k++;
            }
            else
            {
                last->next = pp3;
                last = last->next;
            }
        }
        else
        {
            pp3 = new chainNode<T>;
            pp3->data = pp2->data;
            pp3->next = nullptr;
            pp2 = pp2->next;
            if (k == 1)
            {
                this->head=this->last = pp3;
                k++;
            }
            last->next = pp3;
            last = last->next;
        }
    }
    while (pp1)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp1->data;
        pp3->next = nullptr;
        pp1 = pp1->next;
        if (k == 1)
        {
            this->head = this->last = pp3;
            k++;
        }
        else
        {
            last->next = pp3;
            last = last->next;
        }
    }
    while (pp2)
    {
        pp3 = new chainNode<T>;
        pp3->data = pp2->data;
        pp3->next = nullptr;
        pp2 = pp2->next;
        if (k == 1)
        {
            this->head = this->last = pp3;
            k++;
        }
        last->next = pp3;
        last = last->next;
    }
}

template<class T>
void split2(chain<T>&A,chain<T>& B, chain<T>& C)
{
    chainNode<T>* p = A.gethead();
    int k = 1;
    while (p)
    {
        if (k % 2)
        {
            B.append(p->data);
            k++;
        }
        else
        {
            C.append(p->data);
            k++;
        }
        p = p->next;
    }
}

template <class T>
void chain<T>::split(chain<T>& B, chain<T>& C)
{
    if (!this->head)
        throw "erroe";
    while (B.head)
    {
        erase(1);
    }
    while (C.head)
    {
        erase(1);
    }
    chainNode<T>* p = this->head;
    chainNode<T>* pp = new chainNode<T>;
    pp->next = nullptr;
    pp->data = p->data;
    B.head = B.last = pp;
    if (head->next)
    {
        p = p->next;
        pp = new chainNode<T>;
        pp->next = nullptr;
        pp->data = p->data;
        C.head = C.last = pp;
        p = p->next;
    }
    int k = 1;
    while (p)
    {
        pp = new chainNode<T>;
        pp->data = p->data;
        pp->next = nullptr;
        if (k % 2)
        {
            B.last->next = pp;
            B.last = B.last->next;
            k++;
        }
        else
        {
            C.last->next = pp;
            C.last = C.last->next;
            k++;
        }
        p = p->next;
    }
}

main.cpp文件
// LinkedList.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "LinkedList.h"
#include<iostream>
using namespace std;
int main()
{
    chain<int> list2;
    list2.insert(0, 6);
    list2.insert(0, 4);
    list2.insert(0, 2);
    list2.insert(0, 1);
    list2.insert(0, 3);
    list2.insert(0, 5);
    cout << list2 << endl;

    chain<int> list3;
    chain<int> list4;
    split2(list2,list3,list4);
    cout << list3 << endl;
    cout << list4 << endl;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值