动态数组&双向链表

#include <iostream.h> /*有N支猴子,需要从中选中一个大王,选择的规则如下, 猴子们围成一圈(每个猴子从1到N编号), 从1到M依次报数,每当报到M的猴子出列,紧接着从一个猴子接着报,重新从1开始,直到剩下最下最后一个猴子, 即为大王. 编程实现选出大王,其中N,M由用户从键盘输入. */ class m_k { private: // typedef m_k *LP,*LN,*LPN; m_k* m_pHeader; m_k* m_pPre; m_k* m_pNext; int m_nD; m_k* addToall() { m_k* p = new m_k[m_nD]; return p; } public: m_k() { m_pHeader = NULL; } m_k(int nT) { m_nD=nT; m_pHeader = addToall(); } m_k* ListSortToall() { m_k* ptemp = m_pHeader; int nD = m_nD; if (nD>0) { if (nD>1) { for (int n = 0;n<nD;n++) { (ptemp+n)->m_pNext = (ptemp+n+1); (ptemp+n)->m_nD = 1+n; (ptemp+nD-1-n)->m_pPre = (ptemp+nD-1-n-1); } ptemp->m_pPre = (ptemp+n-1); (ptemp+n-1)->m_pNext = ptemp; /*for (int a=0;a<20;a++){cout<<ptemp->m_nD<<" ";ptemp=ptemp->m_pNext;}cout<<endl;*/ /*ptemp = ptemp->m_pPre;for (int b=0;b<20;b++){cout<<ptemp->m_nD<<" ";ptemp = ptemp->m_pPre;}*/ } else if (nD==1) { ptemp->m_nD = 1; ptemp->m_pNext = ptemp; ptemp->m_pPre = ptemp; } } return ptemp; } int kingofthemonkey(int nM) { if (1==nM)return m_nD; else if (nM>m_nD)return -1; else { m_k *ptemp = m_pHeader; int nNUM = 0; while (true) { ++nNUM; if (nNUM > nM) { nNUM = 1; } if(nNUM == nM)//踢出为相同的数位 { //cout<<ptemp->m_nD<<endl; ptemp->m_pPre->m_pNext = ptemp->m_pNext; ptemp->m_pNext->m_pPre = ptemp->m_pPre; } ptemp = ptemp->m_pNext;//逻辑内存移向下一位置 if (ptemp->m_pNext == ptemp->m_pPre ) { return ptemp->m_nD; } } } } ~m_k() { delete[] m_pHeader; //注意: m_pHeader指向的内存地址并没有发生改变(物理数据结构), 改变的是p->pNext;p->pPer的 逻辑位置(逻辑数据结构) //for (int n = 0;n<20;n++){cout<<" "<<(m_pHeader+n)->m_nD<<" ";} 采取析构时候使用最终一次性删除的办法,避免了无法回档的烦恼优化于双向链表删除临时结点 } }; m_k* pHeader = NULL; void main() { int nD = 100; int nM = 2; m_k Mking(nD); pHeader = Mking.ListSortToall(); int nKing = Mking.kingofthemonkey(nM); //Mking.ListSortToall(); //nKing = Mking.kingofthemonkey(3); cout<<nKing; }

你可能感兴趣的:(动态数组&双向链表)