⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcirlinklm.txt

📁 C++描述的数据结构内容,在C++builder的环境中运行,这是第二部分
💻 TXT
字号:
//双向循环链表的类定义dcirlinkl.h
typedef int ElemType;
//双向链表结点的类型定义
typedef struct DuLNode {
  ElemType  data;
  struct DuLNode *prior;//左指针
  struct DuLNode *next;//右指针
}DuLNode;
#define LEN 20

class DuLinkList
{private:
  DuLNode *head;//指向表头的指针
  DuLNode *curr;//当前结点指针
  int count;// 双向循环链表的结点个数
 public:
//构造函数
  DuLinkList();
//析构函数
  ~DuLinkList(){delete head;}
//创建有序或无序的带头结点的双向循环链表
  DuLNode *CreateCLinkL(int,int,int mark=0);
//清空单循环链表
  void ClearCList();
//求双向循环链表长度
  int CListSize();
//检查双向循环链表是否为空
  bool CListEmpty();
//返回指向第pos个结点的指针
  DuLNode *Index(int pos);
//返回双向循环链表中指定序号的结点值
  ElemType GetElem(int pos);
//遍历双向循环链表
  void TraverseCList();
//当前指针curr指向pos结点并返回curr
  DuLNode *Reset(int pos=0);
//当前指针curr指向下一结点并返回
  DuLNode *Next();
//当前指针curr指向上一结点并返回
  DuLNode *Prior();
// 判双向循环链表当前指针curr==head 否
  bool EndOCList();
//判双向循环链表当前指针curr->next是否到达表尾
  bool EndCList();
//判双向循环链表当前指针curr->prior是否到达表尾
  bool PEndCList();
//删除curr->next所指结点,并返回所删结点的data
  ElemType DeleteNt();
//从双向循环链表中查找元素
  bool FindCList(ElemType& item);
//更新双向循环链表中的给定元素
  bool UpdateCList(const ElemType &item,ElemType &e);
//向链表中第pos个结点前插入域值为item的新结点
  void InsertCLfront(const ElemType& item,int pos);
//向链表中第pos个结点后插入域值为item的新结点
  void InsertCLafter(const ElemType& item,int pos);
//从链表中删除第pos个结点并返回被删结点的data
  ElemType DeleteCList(int pos);
};
//双向循环链表的实现dcirlinkl.cpp
#include<iostream.h>
#include<stdlib.h>
#include"dcirlinkl.h"
//构造函数
DuLinkList::DuLinkList()
{head=new DuLNode;
 head->prior=head;
 head->next=head;
 curr=NULL;
 count=0;
}
//创建有序或无序的带头结点的双向循环链表
DuLNode *DuLinkList::CreateCLinkL(int n,int m,int mark)
{ElemType x,a[LEN];
 srand(m);
 for(int i=0;i<n;i++) a[i]=rand()%100;
 for(int i=0;i<n-1;i++)
  {int k=i;
   for(int j=i+1;j<n;j++)
    if(a[k]>a[j]) k=j;
   if(k!=i)
   {x=a[k];a[k]=a[i];a[i]=x;}}
 DuLNode *p;
 head=new DuLNode;
 head->prior=NULL;
 head->next=curr=p=new DuLNode;
 curr->prior=head;
 for(int i=0;i<n;i++){
  if(mark==1) p->data=a[i];//升序
  else
   if(mark==-1) p->data=a[n-1-i];//降序
   else p->data=rand()%100;//无序
  if(i<n-1){curr=curr->next=new DuLNode;
   curr->prior=p;p=curr;}
  count++;}
 head->prior=curr;
 curr->next=head;
 return head;
}
//清空双向循环链表
void DuLinkList::ClearCList()
{DuLNode *cp,*np;
 cp=head->next;
 while(cp!=head)
 {np=cp->next;delete cp;cp=np;}
 head=NULL;
}
//求双向循环链表长度
int DuLinkList::CListSize()
{DuLNode* p=head->next;
 int i=0;
 while(p!=head)
  {i++;p=p->next;}
 return i;
}
//检查双向循环链表是否为空
bool DuLinkList::CListEmpty()
{return head->next==head;}
//返回指向第pos个结点的指针
DuLNode *DuLinkList::Index(int pos)
{if(pos<1)
  {cerr<<"pos is out range!"<<endl;exit(1);}
 DuLNode* p=head->next;
 int i=0;
 while(p!=head)
  {i++;
   if(i==pos) break;
   p=p->next;}
 if(p!=head) return p;
 else {cerr<<"pos is out range!"<<endl;
  return NULL;}
}
//返回双向循环链表中指定序号的结点值
ElemType DuLinkList::GetElem(int pos)
{if(pos<1)
 {cerr<<"pos is out range!"<<endl;exit(1);}
 DuLNode* p=head->next;
 int i=0;
 while(p!=head)
  {i++;
   if(i==pos) break;
   p=p->next;}
 if(p!=head) return p->data;
 else {cerr<<"pos is out range!"<<endl;
  return pos;}
}
//遍历双向循环链表
void DuLinkList::TraverseCList()
{DuLNode *p=head->next;
 while(p!=head)
  {cout<<setw(4)<<p->data;
   p=p->next;}
 cout<<endl;
}
//当前指针curr指向pos结点并返回curr
DuLNode *DuLinkList::Reset(int pos)
{DuLNode* p=curr=head->next;
 int i=-1;
 while(p!=head)
  {i++;
   if(i==pos) break;
   p=p->next;curr=curr->next;}
 return curr;
}
//当前指针curr指向下一结点并返回
DuLNode *DuLinkList::Next()
{curr=curr->next;
 return curr; 
}
//当前指针curr指向上一结点并返回
DuLNode *DuLinkList::Prior()
{curr=curr->prior;
 return curr;
}
// 判双向循环链表当前指针curr==head 否
bool DuLinkList::EndOCList()
{return curr==head;}
//判双向循环链表当前指针curr->next是否到达表尾
bool DuLinkList::EndCList()
{return curr->next==head;}
//判双向循环链表当前指针curr->prior是否到达表尾
bool DuLinkList::PEndCList()
{return curr->prior==head;}
//删除curr->next所指结点,并返回所删结点的data
ElemType DuLinkList::DeleteNt()
{DuLNode *p=curr->next;
 curr->next=p->next;
 curr->next->next->prior=p->prior;
 ElemType data=p->data;
 delete p;
 count--;
 return data;
}
//从双向循环链表中查找元素
bool DuLinkList::FindCList(ElemType& item)
{DuLNode* p=head->next;
 while(p!=head)
  if(p->data==item)
   {item=p->data;return true;}
  else p=p->next;
 return false;
}
//更新双向循环链表中的给定元素
bool DuLinkList::UpdateCList(const ElemType &item,ElemType &e)
{DuLNode* p=head->next;
 while(p!=head)  //查找元素
  if(p->data==item) break;
  else p=p->next;
 if(p==head) return false;
 else {  //更新元素
  p->data=e;return true;}
}
//向链表中第pos个结点前插入域值为item的新结点
void DuLinkList::InsertCLfront(const ElemType& item,int pos)
{DuLNode *newP=new DuLNode;
 newP->data=item;
 DuLNode* p=head->next;
 int i=0;
 while(p!=head)
  {i++;
   if(i==pos) break;
   p=p->next;}
 newP->prior=p->prior;
 p->prior->next=newP;
 newP->next=p;
 p->prior=newP;
 count++;
}
//向链表中第pos个结点后插入域值为item的新结点
void DuLinkList::InsertCLafter(const ElemType& item,int pos)
{DuLNode *newP=new DuLNode;
 newP->data=item;
 DuLNode* p=head->next;
 int i=-1;
 while(p!=head)
  {i++;
   if(i==pos) break;
   p=p->next;}
 newP->prior=p->prior;
 p->prior->next=newP;
 newP->next=p;
 p->prior=newP;
 count++;
}
//从链表中删除第pos个结点并返回被删结点的data
ElemType DuLinkList::DeleteCList(int pos)
{if(pos<1)
  {cerr<<"pos is out range!"<<endl;exit(1);}
 DuLNode *p=head->next;
 ElemType data;
 int i=0;
 while(p!=head)
  {i++;
   if(i==pos) break;
   p=p->next;}
 if(p!=head)
  {data=p->data;
   p->prior->next=p->next;
   p->next->prior=p->prior;
   delete []p;count--;return data;}
 else return pos;  
}
//双向循环链表的测试与应用dcirlinklm.cpp
#include<iomanip.h>
#include "dcirlinkl.cpp"
void main()
{cout<<"dcirlinklm.cpp运行结果:\n";
 int m=150,i,n=10,x,it;
 bool f;
 DuLinkList p,t,q,mylink;
 p.CreateCLinkL(n,m,1);
 if(p.CListEmpty()) cout<<"双向循环链表p空!\n";
 else cout<<"双向循环链表p非空!\n";
 cout<<"双向循环链表p(升序):\n";
 p.TraverseCList();
 if(p.CListEmpty()) cout<<"双向循环链表p空!\n";
 else cout<<"双向循环链表p非空!\n";
 if(p.EndCList()) cout<<"双向循环链表p满!\n";
 else cout<<"双向循环链表p非满!\n";
 cout<<"双向循环链表t(无序):\n";
 t.CreateCLinkL(n-2,m);
 t.TraverseCList();
 cout<<"双向循环链表t的长度:"<<t.CListSize()<<endl;
 cout<<"双向循环链表q(降序):\n";
 q.CreateCLinkL(n,m,-1);
 q.TraverseCList();
 cout<<"双向循环链表q的长度:"<<q.CListSize()<<endl;
 cout<<"链表q的第1个元素:"<<q.GetElem(1)<<endl;
 cout<<"链表q的第1个元素地址:"<<q.Index(1)<<endl;
 cout<<"链表q的第5个元素:"<<q.GetElem(5)<<endl;
 cout<<"链表q的第5个元素地址:"<<q.Index(5)<<endl;
 cout<<"链表q的第10个元素:"<<q.GetElem(10)<<endl;
 cout<<"链表q的第10个元素地址:"<<q.Index(10)<<endl;
 cout<<"链表q的curr->next所指元素地址:"<<q.Next()<<endl;
 x=65;it=66;
 if(q.FindCList(x)) cout<<x<<"查找成功!\n";
 else cout<<x<<"查找不成功!\n";
 if(q.UpdateCList(x,it)) cout<<x<<"更新成功!\n";
 else cout<<x<<"更新不成功!\n";
 cout<<"更新后双向循环链表q:\n";
 q.TraverseCList();
 cout<<"插入后双向循环链表q:\n";
 it=100;q.InsertCLfront(it,1);
 q.TraverseCList();
 cout<<"插入后双向循环链表q:\n";
 it=101;q.InsertCLfront(it,5);
 q.TraverseCList();
 cout<<"插入后双向循环链表q:\n";
 it=102;q.InsertCLfront(it,13);
 q.TraverseCList();
 cout<<"插入后q表长:"<<q.CListSize()<<endl;
 cout<<"第1个数:"<<q.DeleteCList(1)<<"删除成功!\n";
 cout<<"删除后q表长:"<<q.CListSize()<<endl;
 q.TraverseCList();
 cout<<"第5个数:"<<q.DeleteCList(5)<<"删除成功!\n";
 cout<<"删除后q表长:"<<q.CListSize()<<endl;
 q.TraverseCList();
 cout<<"第11个数:"<<q.DeleteCList(11)<<"删除成功!\n";
 cout<<"删除后q表长:"<<q.CListSize()<<endl;
 q.TraverseCList();
 cout<<"删除的数为:"<<q.DeleteNt()<<endl;
 cout<<"删除后q表长:"<<q.CListSize()<<endl;
 q.TraverseCList();
 cout<<"求解约瑟夫(Josephus)问题\n";
 cout<<"输入人数n:";cin>>n;
 cout<<"输入第次数m:";cin>>m;
 for(i=0;i<n;i++) mylink.InsertCLafter(i+1,i);
 cout<<"员工编号依次为:";
 DuLNode *w=mylink.Reset();
 while(!mylink.EndOCList())
  {cout<<setw(3)<<w->data;
   w=mylink.Next();}
 cout<<endl;
 cout<<"删除次序依次为:\n";
 mylink.Reset(-1);
 for(i=0;i<n-1;i++)
 {for(int j=0;j<m-1;j++)
  {w=mylink.Next();
   if(mylink.EndOCList()) w=mylink.Next();}
  if(mylink.EndCList()) w=mylink.Next();
  cout<<"删除第"<<mylink.DeleteNt()<<"人\n";}
 cout<<"最后剩下的是:第"<<mylink.GetElem(1)<<"个人\n";
 cin.get();cin.get();}
dcirlinklm.cpp运行结果:
双向循环链表p非空!
双向循环链表p(升序):
  25  27  27  29  44  65  78  79  97  99
双向循环链表p非空!
双向循环链表p满!
双向循环链表t(无序):
  99  25  45  46  43  33  61  96
双向循环链表t的长度:8
双向循环链表q(降序):
  99  97  79  78  65  44  29  27  27  25
双向循环链表q的长度:10
链表q的第1个元素:99
链表q的第1个元素地址:12603940
链表q的第5个元素:65
链表q的第5个元素地址:12604004
链表q的第10个元素:25
链表q的第10个元素地址:12604084
链表q的curr->next所指元素地址:12603924
65查找成功!
65更新成功!
更新后双向循环链表q:
  99  97  79  78  66  44  29  27  27  25
插入后双向循环链表q:
 100  99  97  79  78  66  44  29  27  27  25
插入后双向循环链表q:
 100  99  97  79 101  78  66  44  29  27  27  25
插入后双向循环链表q:
 100  99  97  79 101  78  66  44  29  27  27  25 102
插入后q表长:13
第1个数:100删除成功!
删除后q表长:12
  99  97  79 101  78  66  44  29  27  27  25 102
第5个数:78删除成功!
删除后q表长:11
  99  97  79 101  66  44  29  27  27  25 102
第11个数:102删除成功!
删除后q表长:10
  99  97  79 101  66  44  29  27  27  25
删除的数为:99
删除后q表长:9
  97  79 101  66  44  29  27  27  25
求解约瑟夫(Josephus)问题
输入人数n:8
输入第次数m:3
员工编号依次为:  1  2  3  4  5  6  7  8
删除次序依次为:
删除第3人
删除第6人
删除第1人
删除第5人
删除第2人
删除第8人
删除第4人
最后剩下的是:第7个人




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -