数据结构与算法分析课后习题第三章(2)

希望大家看过后对我自己写的这些笨方法提出意见,如果有问题也请及时指出,谢谢^^

Exercise 3.2 Swap two adjacent elements by adjusting only the links ( and not the data ) using

a. Singly linked list.

b. Doubly linked list 

//single.hpp

#ifndef SINGLE_H__
#define SINGLE_H__

template<typename Object>
class SLList {
private:
 class Node {
 public:
  Node(const Object& ob = Object(), Node* n = 0) :
    data(ob), next(n) {}

 public:
  Node* next;
  Object data;
 };

public:
 class const_iterator {
 public:
  const_iterator() : current(0) {}
  
  const Object& operator*() const{ return retrieve(); }
  const_iterator& operator++()
  {
   current = current->next;
   return *this;
  }

  const_iterator& operator++(int)
  {
   const_iterator old = *this;
   ++(*this);
   return old;
  }

  bool operator==(const const_iterator& rhs) const
  { return current == rhs.current; }
  bool operator!=(const const_iterator& rhs) const
  { return !(*this == rhs); }

 protected:
  const_iterator(Node* p) : current(p) {}

  Object& retrieve() const { return current->data; }
  Node* current;

  friend class SLList<Object>;
 };

 class iterator : public const_iterator {
 public:
  iterator(){}

  Object& operator*() { return retrieve(); }
  const Object& operator*() const { return retrieve(); }

  iterator& operator++()
  {
   current = current->next;
   return *this;
  }

  iterator& operator++(int)
  {
   iterator old = *this;
   ++(*this);
   return old;
  }

  bool operator==(const iterator& rhs)
  { return current == rhs.current; }
  bool operator!=(const iterator& rhs)
  { return !(*this == rhs); }

 private:
  iterator(Node* p) : const_iterator(p){}

  friend class SLList<Object>;
 };

public:
 SLList() { init(); }
 ~SLList()
 {
  clear();
  delete head;
  delete tail;
 }

 SLList(const SLList& rhs)
 {
  init();
  *this = rhs;
 }
 SLList& operator=( const SLList& rhs)
 {
  if(*this == rhs)
   return *this;

  clear();
  for(const_iterator it = rhs.begin(); it != rhs.end(); ++it)
   push_back(*it);

  return *this;
 }

public:
 bool empty() { return theSize == 0; }
 void clear()
 {
  while(!empty())
   pop_front();
 }
 void pop_front()
 { 
  Node* p = head->next;
  head->next = head->next->next;
  delete p;
  --theSize;
 }
 void push_front(const Object& ob)
 { 
  Node* p = head->next;
  head->next = new Node(ob, p);
  ++theSize;
 }

 iterator begin(){ return iterator(head->next); }
 const_iterator begin() const { return const_iterator(head->next); }
 iterator end() { return iterator(tail); }
 const_iterator end() const { return const_iterator(tail); }

 Object& front() { return *begin(); }
 const Object& front() const { return *begin(); }

 void swapAdj(iterator it/*first, iterator second*/)
 {
  int cnt = 0;
  Node* p = it.current;
  iterator i = iterator(this->head);
  while(i != it)
  {
   ++i;
   ++cnt;
  }
   
  --cnt;
  i = iterator(this->head);
  while(cnt > 0)
  {
   ++i;
   --cnt;
  }

  Node* pi = i.current;
  pi->next = p->next;
  p->next = pi->next->next;
  pi->next->next = p;
 }
private:
 Node* head;
 Node* tail;
 unsigned int theSize;

 void init()
 {
  head = new Node();
  tail = new Node();
  head->next = tail;
  tail->next = 0;
  theSize = 0;
 }
};

 

#endif

//double.hpp

//中间加了判断迭代器的功能,应用时该用throw抛出异常来代替现在的cerr

//另,这个判断迭代器功能只用在了insert里,别的懒得写了

#ifndef DOUBLE_HPP__
#define DOUBLE_HPP__

#include <iostream>
#include <cassert>

template<typename Object>
class List {
private:
 class Node {
 public:
  Node(const Object& d = Object(), Node* p = 0, Node* n = 0) : data(d), next(n), prev(p) {}

 public:
  Object data;
  Node* next;
  Node* prev;
 };

public:
 class Const_Iterator {
 public:
  Const_Iterator() : current(0){}

  const Object& operator* () const { return retrieve(); }
  
  Const_Iterator& operator++()
  {
   current = current->next;
   return *this;
  }

  Const_Iterator& operator++(int)
  {
   Const_Iterator old = *this;
   ++(*this);
   return old;
  }

  Const_Iterator& operator--()
  {
   current = current->prev;
   return *this;
  }

  Const_Iterator& operator--(int)
  {
   Const_Iterator old = *this;
   --(*this);
   return old;
  }

  bool operator==(const Const_Iterator& rhs) const
  {
   return current == rhs.current;
  }

  bool operator!=(const Const_Iterator& rhs) const
  {
   return !(*this == rhs);
  }
 protected:
  Node* current;

  Object& retrieve() const { return current->data; }

  Const_Iterator(const List<Object> &lst, Node* p) : theList(&lst), current(p) {}

  void assertValid()
  {
   assert(theList != 0 || current != 0 || current != theList->head);
  }

  const List<Object> *theList;

  friend class List<Object>;

 };

 class Iterator : public Const_Iterator {
 public:
  Iterator(){}
  
  Object& operator*() { return retrieve(); }
  Object& operator*() const { return retrieve(); }

  Iterator& operator++()
  {
   current = current->next;
   return *this;
  }

  Iterator& operator++(int)
  {
   Node old = *this;
   ++(*this);
   return old;
  }

  Iterator& operator--()
  {
   current = current->prev;
   return *this;
  }

  Iterator& operator--(int)
  {
   Node old = *this;
   --(*this);
   return old;
  }

  bool operator==(const Iterator& rhs) const
  {
   return current == rhs.current;
  }

  bool operator!=(const Iterator& rhs) const
  {
   return !(*this == rhs);
  }

 private:
  Iterator(List<Object> &lst, Node *p) : Const_Iterator(lst, p) {}

  friend class List<Object>;

 };

public:
 List()
 {
  init();
 }
 List(const List& rhs)
 {
  init();
  *this = rhs;
 }
 ~List()
 {
  Clear();
  delete head;
  delete tail;
 }
 List& operator=(const List& rhs)
 {
  if(rhs == *this)
   return *this;

  Clear();
  for(Const_Iterator it = rhs.Begin(); it != rhs.End(); ++ it)
   Push_Back(*it);

  return *this;
 }

 Iterator Begin() { return Iterator(*this, head->next); }
 Const_Iterator Begin() const { return Const_Iterator(*this, head->next); }

 Iterator End() { return Iterator(*this, tail); }
 Const_Iterator End() const { return Const_Iterator(*this, tail); }
 
 unsigned int Size() const { return theSize; }
 bool Empty() const { return theSize == 0; }

 void Clear()
 {
  while(!Empty())
   Pop_Front();
 }

 Object& Front() { return *Begin(); }
 const Object& Front() const { return *Begin(); }

 Object& Back() { return *(--End()); }
 const Object& Back() const { return *(--End()); }

 void Push_Front(const Object& ob)
 {
  Insert(Begin(), ob);
 }

 void Push_Back(const Object& ob)
 {
  Insert(End(), ob);
 }

 void Pop_Front() { Erase(Begin()); }
 void Pop_Back() { Erase(--End()); }

 Iterator Insert(Iterator it, const Object& ob)
 {
  it.assertValid();
  if(it.theList != this)
   std::cerr << "Not the same list/n";
  else
  {
   Node* p = it.current;
   ++theSize;
   return Iterator(*this, p->prev = p->prev->next = new Node(ob, p->prev, p));
  }
 }
 Iterator Erase(Iterator it)
 {
  Node* p = it.current;
  Iterator retVal(*this, p->next);
  p->prev->next = p->next;
  p->next->prev = p->prev;
  delete p;
  --theSize;

  return retVal;
 }

 Iterator Erase(Iterator start, Iterator end)
 {
  for(Iterator it = start; it != end; )
   it = Erase(it);
  
  return end;
 }

 void swapAdj(Iterator it)
 {
  Node* first = it.current;
  Node* second = (++it).current;

  second->next->prev = first;
  first->prev->next = second;
  first->next = second->next;
  
  second->prev = first->prev;
  second->next = first;
  first->prev = second;
 }  

private:
 unsigned int theSize;
 Node* head;
 Node* tail;

 void init()
 {
  theSize = 0;
  head = new Node();
  tail = new Node();
  head->next = tail;
  tail->prev = head;
 }
};

#endif

 

//main.cpp

#include "single.hpp"
#include "double.hpp"
#include <iostream>

int main()
{
 //SLList<int> l;
 List<int> dl;
 //l.push_front(2);
 //l.push_front(1);
 //l.push_front(3);

 dl.Push_Back(3);
 dl.Push_Back(2);
 dl.Push_Back(1);

 for(List<int>::Const_Iterator it = dl.Begin(); it != dl.End(); ++it)
  std::cout << *it << std::endl;

 List<int>::Iterator it = dl.Begin();
 ++it;
 dl.swapAdj(it);

 std::cout << "after swap: " << std::endl;

 for(List<int>::Const_Iterator it = dl.Begin(); it != dl.End(); ++it)
  std::cout << *it << std::endl;

 std::cout << "/n";

 for(List<int>::Const_Iterator it = --dl.End(); it != --dl.Begin(); --it)
  std::cout << *it << std::endl;

 return 0;
}

1. 经过以下栈运算后,x的值是( )。 InitStack(s); Push(s,'a'); Push(s,'b'); Pop(s,x); Gettop(s,x); A. a B. b C. 1 D. 0 2.循环队列存储在数组A[0..m]中,则入队时的操作为( )。 A.rear=rear+1 B. rear=(rear+1) mod(m-1) C. rear=(rear+1)mod m D. rear=(rear+1) mod(m+1) 3. 栈和队列的共同点是( )。 A.都是先进先出 B.都是先进后出 C.只允许在端点处插入和删除元素 D.没有共同点 4. 若用一个大小为6的数组来实现循环队列,且当 rear 和 front 的值分别为 0 和 3。当从队列中删除一个元素,再插入两个元素后,rear 和 front 的值分别为:( )。 A.1 和 5 B.2 和 4 C.4 和 2 D.5 和 1 5. 程序填顺序循环队列的类型定义如下: typedef int ET; typedef struct{ ET *base; int Front; int Rear; int Size; }Queue; Queue Q; 队列 Q 是否“满”的条件判断为( C )。 A.(Q.Front+1)=Q.Rear B.Q.Front=(Q.Rear+1) C.Q.Front=(Q.Rear+1)% Q.size D.(Q.Front+1) % Q.Size=(Q.Rear+1)% Q.size 6. 若进栈序列为1,2,3,4,进栈过程中可以出栈,则( )不可能是一个出栈序列。 A.3,4,2,1 B.2,4,3,1 C.1,4,2,3 D.3,2,1,4 7. 向顺序存储的循环队列 Q 中插入新元素的过程分为三步: ( )。 A.进行队列是否空的判断,存入新元素,移动队尾指针 B.进行队列是否满的判断,移动队尾指针,存入新元素 C.进行队列是否空的判断,移动队尾指针,存入新元素 D.进行队列是否满的判断,存入新元素,移动队尾指针 8. 关于栈和队列,( )说法不妥。 A. 栈是后进先出表 B. 队列是先进先出表 C. 递归函数在执行时用到栈 D. 队列非常适用于表达式求值的算符优先法 9. 若用数组S[0..m]作为两个栈S1和S2的共同存储结构,对任何一个栈,只有当S全满时才不能作入栈操作。为这两个栈分配空间的最佳方案是( )。 A.S1的栈底位置为0,S2的栈底位置为m B.S1的栈底位置为0,S2的栈底位置为m/2 C.S1的栈底位置为1,S2的栈底位置为m D.S1的栈底位置为1,S2的栈底位置为m/2 二、程序填空题(没特别标注分数的空的为3分,共 23 分)。 1.下面的算法是将一个整数e压入堆栈S,请在空格处填上适当的语句实现该操作。 typedef struct{ int *base; int *top; int stacksize; }SqStack; int Push(SqStack S,int e) { if ( S.top- S.base>= S.stacksize ) { S.base=(int *) realloc(S.base,(S.stacksize+1)*sizeof(int)); if( !S.base ) { printf(“Not Enough Memory!\n”); return(0); } S.top= S.base+ S.stacksize ; S.stacksize= S.stacksize+1 ; } * S.top++=e ; return 1; } 2. 在表达式:6+5+3*7/(4+9/3-2)求值过程中,处理到2时刻,运算符栈的状态为: + / ( - (4分),操作数栈的内容为11,21,7,2(4分)。 3. 递调用时,处理参数及返回地址,要用一种称为 栈 的数据结构。 4. 设循环队列中数组的下标范围是1-n,其头尾指针分别为f和r,则其元素个数为_(r-f+n) mod n。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值