数据结构——循环链表、仅设尾指针的循环链表、约瑟夫环

来源:互联网 发布:网络视听许可证名单 编辑:程序博客网 时间:2024/06/05 20:55
  1 //循环链表,链表的尾结点的link域中不是NULL,而是存放了指针链表开始结点的指针  2 ////设p是在循环链表中逐个结点检测指针,则在判断p是否达到链表的链尾时p->link == first  3   4   5 //循环链表的结构定义  6 typedef int DataType;  7 typedef struct node//循环链表定义  8 {  9     DataType data;//结点数据 10     struct node *link;//后继结点指针 11 }CirNode, *CirList; 12  13 //循环链表的插入算法 14 int Insert(CirNode *first, int i, DataType x) 15 {//将新元素x插入在循环链表中第i(1<=i)个结点位置。如果插入失败函数返回0,否则函数返回1. 16     if(i<1) 17         return 0; 18     CirNode *p = first, *q; 19     int k = 0; 20     while(p->link != first && k< i-1)//定位于第i-1个结点,如果i超出表长度则插入到链尾 21     { 22         p = p->link; 23         k++; 24     } 25     q = new CirNode;//创建新结点用q指示 26     if(!q){cerr<<"存储分配错误!\n"; exit(1);} 27     q->data = x; 28     q->link = p->link;//将*q链接在*p之后 29     p->link = p; 30     return 1;//插入成功 31 } 32 

 33 //循环链表的删除算法 34 int Remove(CirList& first, int i, DataType& x) 35 {//将链表中的第i个元素删去,通过引用型参数x返回该元素的值 36 //如果i不合理则删除失败,函数返回0, 否则函数返回1 37     if(i<1)return 0;//i太小,不合理 38     CirNode *p = first, *q; 39     int k = 0; 40     while(p->link != first && k < i-1) 41     { 42         p = p->link; 43         k++; 44     } 45     //if(p->link == L)//i太大,被删结点不存在 46      //   return 0; 47     q = p->link;//用q保存被删结点地址 48     p->link = q->link;//重新链接,将被删结点从链中摘下 49     x = q->data;//取出被删结点的数据 50     delete q;//释放结点 51     return 1; 52 }





 55 //仅设尾指针的循环链表 56 //不用表头指针而用一个指向表尾结点的指针rear标识,可以将插入和删除的时间复杂度提高到O(l) 57 //删除循环链表的指针p所指示的结点 58 int Remove(CirNode* &p, DataType& x) 59 {//将链表中的指针p所指示结点的元素删去,通过引用型参数x返回该元素的值 60  61     CirNode *q = p->link; 62     x = p->data;//取出p结点的元素 63     p->data = q->data;//下一结点的元素复制给被删结点 64     p->link = q->link;//重新链接,将下一结点从链中摘下 65     delete q;//释放下一结点 66     return 1; 67 } 68 //在循环尾端插入一个由newNode所指示的新结点 69 int Insert(CirNode* &p, DataType& x) 70 {//rear为尾指针 71     CirNode *newNode; 72     newNode->data = x; 73     newNode->link = rear->link; 74     rear->link = newNode; 75 }

 78 //求解约瑟夫环问题 79  80 void Josephus(CirNode* & Js, int n, int m) 81 { 82     CirNode *p = Js, *pre = NULL; 83     for(int i = 0; i<n-1; i++)//执行n-1趟虚循环 84     { 85         for(int j = 0; j<m; j++)//令p向后移动m-1个结点 86         { 87             pre = p; 88             p=p->link; 89         } 90         cout<<"出列的人"<<p->data<<endl;//输出结点*p的数据 91         pre->link = p->link; 92         delete p;//删去结点*p 93         p = pre->link; 94     } 95     cout<<"最终优胜者是:"<<p->data<<endl;//输出结果 96 } 97 int main() 98 { 99     CirNode *clist, *last;100     int n, m;101     clist = new CirNode;//创建循环链表头结点102     //if(!clist){cerr<<"存储分配失败!\n"; exit(1);}103     clist->link = clist;104     last = clist;//循环链表置空105     cout<<"输入游戏者人数和报数间隔:";106     cin>>n>>m;107     for(int i=1; i<=n; i++)108     {109         last->link = new CirNode;//创建链表结点110         if(!last->link){cerr<<"存储分配失败!\n"; exit(1);}111         last = last->link;//逐个插入结点形成约瑟夫环112         last->data = i;113     }
114     Josephus(clist, n, m);//解决约瑟夫环问题115     return 0;116 }117 //算法时间复杂度O(n*m)


约瑟夫环实现(C语言)

  1 #include"stdio.h"  2 #include <malloc.h>  3   4 //单链表结构体  5 typedef struct Node  6 {  7     int index;  8     int key;  9     struct Node *next; 10 }LinkNode, *LinkList; 11  12 //创建链表 13 LinkList CreatLinkList() 14 { 15     LinkList L; 16     L = (LinkList)malloc(sizeof(Node)); 17     printf("请输入第一个人的密码:\n"); 18     int key; 19     scanf_s("%d",&key); 20     L->key = key; 21     L->index = 1; 22     L->next = L; 23     Node *tail; 24     Node *s; 25     tail = L; 26  27     printf("请输入构建循环单链表的长度-1:");//除去已经输入的第一个人 28     int len; 29     scanf_s("%d",&len); 30  31     for (int i = 1; i < len; i++) 32     { 33         s = (Node *)malloc(sizeof(Node)); 34         scanf_s("%d", &s->key); 35         s->index = i + 1; 36         s->next = tail->next; 37         tail->next = s;
 38         tail = s; 39     } 40     return L; 41 } 42  43 //约瑟夫环的实现 44 void yuesef(LinkList L,int Password) 45 { 46     int count = 1; 47     Node *p; 48     Node *s, *r; 49     p = L; 50     while (p->next != p) 51     { 52         if (count == Password - 1) 53         { 54             printf("下标:%d  密码:%d\n", p->next->index, p->next->key); 55             s = p->next; 56             p->next = s->next; 57             Password = s->key; 58             while (Password == 1 && p->next != p) 59             { 60                 printf("下标:%d  密码:%d\n", p->next->index, p->next->key); 61                 r = p->next; 62                 p->next = r->next; 63                 Password = r->key; 64                 free(r); 65             } 66             free(s); 67             count = 1; 68             p = p->next; 69         } 70         else 71         { 72             p = p->next; 73             count++;
 74         } 75     } 76     printf("下标:%d  密码:%d\n", p->index, p->key); 77 } 78  79 int main(void) 80 { 81     LinkList L; 82     L = CreatLinkList(); 83     Node *p; 84     p = L; 85     printf("%d %d \n", p->index, p->key); 86     p = p->next; 87     //单链表的遍历 88     while (p != L) 89     { 90         printf("%d %d \n", p->index, p->key); 91         p = p->next; 92     } 93     printf("请输入初始关键值:\n"); 94     int Password; 95     scanf_s("%d",&Password); 96     yuesef(L, Password); 97     getchar(); 98     getchar(); 99     return 0;100 }






原创粉丝点击