数据结构第二次作业

来源:互联网 发布:电脑桌面的便签软件 编辑:程序博客网 时间:2024/05/16 00:43

数据结构第二次作业

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;    }}//这个还是没有完成77template <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;}
0 0