說一下思路,?
創(chuàng)建,?遍歷,?求長度...?略
主要是?viewList()?函數(shù)中的?那個(gè)?while()?循環(huán)有點(diǎn)繞,?本來想的是?,?當(dāng)?計(jì)數(shù)?達(dá)到上限時(shí),?就把這個(gè)值?輸出,?然后?將這個(gè)結(jié)點(diǎn)從鏈表中刪除
當(dāng)寫寫發(fā)現(xiàn),?每個(gè)好的標(biāo)志,?早知道就在結(jié)構(gòu)體中?多加一個(gè)?指示變量了,?(輸出過就?跳過,?沒有輸出過,?計(jì)數(shù)器?就加?1?)
這個(gè)還是有點(diǎn)麻煩的.?加了一個(gè)指針?永遠(yuǎn)指向?所?刪除結(jié)點(diǎn)的?前面的那個(gè)結(jié)點(diǎn),?
這樣寫,?還是有點(diǎn)不好的....
這是測試后代碼:
#include?<stdio.h>
#include?<stdlib.h>
#include?<malloc.h>
typedef?struct?Node{
int?data;
struct?Node?*pNext;
}?LNode,?*LIST;
/*函數(shù)聲明*/
LIST?createList();
void?traverseList(LIST?pHead);
int??ListLength(LIST?pHead);
void?viewList(LIST?pHead);
int?main(){
LIST?List?=?createList();??//?創(chuàng)建?
traverseList(?List?);????//?遍歷第一次?
viewList(List);??????????????//?輸出?
return?0;????????
}
/*?單循環(huán)鏈表的創(chuàng)建不用注釋了吧?*/?
LIST?createList()?{
int?n,?i;
LIST?pNew,?pHead,?pTail;?//定義頭結(jié)點(diǎn),?尾結(jié)點(diǎn)?
pHead?=?(LIST)malloc(sizeof(LNode));
if(pHead?==?NULL){
exit(-1);
}
pTail?=?pHead;
printf("輸入人數(shù):?");
scanf("%d",?&n);
for(i?=?0;?i?<?n;?++i){
pNew?=?(LIST)malloc(sizeof(LNode));
if(pHead?==?NULL){
exit(-1);
}
pNew->data?=?i+1;
pTail->pNext?=?pNew;
pTail?=?pNew;//始終將新產(chǎn)生的結(jié)點(diǎn)作為尾結(jié)點(diǎn)?
}
pTail->pNext?=?pHead;
return?pHead;
}
/*?遍歷?*/?
void?traverseList(LIST?pHead){
LIST?p?=?pHead->pNext;
while(p?!=?pHead){
printf("%d?",?p->data);
p?=?p->pNext;?
}
printf("\n");
return?;
}
/*?求長度,??和遍歷差不多?*/?
int??ListLength(LIST?pHead){
int?len?=?0;
LIST?p?=?pHead->pNext;
while(p?!=?pHead){
++len;
p?=?p->pNext;?
}
return?len;
}?
/*?這個(gè)是主要的?*/?
void?viewList(LIST?pHead){
int?i?=?1;
int?j?=?0;
int?cnt?=?1;?//作為計(jì)數(shù)
int?max;//最大上限
//首先鏈表不能為空
if(?pHead->pNext?==?pHead){
return?;?
}?
//最大上限不能為小于?0?的數(shù)?
printf("輸入報(bào)數(shù)最大上限為:?");
scanf("%d",?&max);
if(max?<=?0){
printf("輸入報(bào)數(shù)最大上限值有誤,程序終止!!!\n?");
exit(-1);
}
printf("\n");
//人員編號(hào)不能超過實(shí)有人數(shù)?&&?不能為負(fù)?
printf("輸入第一個(gè)報(bào)數(shù)的人員的編號(hào):?");
scanf("%d",?&j);
if(j?<?1?||?j?>?ListLength(pHead)){
printf("輸入第一個(gè)報(bào)數(shù)的人員的編號(hào)?有誤!!!\n?程序退出!");
exit(-1)?;?
}?
//?將?p?指向第一個(gè)報(bào)數(shù)的員工?
LIST?p?=?pHead->pNext;
LIST?pp?=?pHead;//pp?永遠(yuǎn)指向?p?指向的前面的那個(gè)結(jié)點(diǎn)?
LIST?q;?//作為臨時(shí)存儲(chǔ)?需刪除的結(jié)點(diǎn)?
while(p?!=?pHead){
if(i?==?j)
break;
p?=?p->pNext;
pp?=?pp->pNext;
? ++i;
}?
/*??這個(gè)循環(huán)是重點(diǎn)?*/?
while(?ListLength(pHead)?!=?0){
if(?cnt?!=?max?)?{
p?=?p->pNext;
pp?=?pp->pNext?;
if(p?!=?pHead)
++cnt;
}?else?{
printf("%d?",?p->data);
q?=?p;
p?=?p->pNext;
pp->pNext?=?p;
free(q);
cnt?=?1;
}
} ?
}
這是所有代碼, 包括垃圾代碼, 各種思路, 雖然不是很重要, 但我覺得還是有必要
#include?<stdio.h>
#include?<stdlib.h>
#include?<malloc.h>
#define?OK?1
#define?ERROR?0
typedef?struct?Node{
int?data;
struct?Node?*pNext;
}?LNode,?*LIST;
LIST?createList();
void?traverseList(LIST?pHead);
int??ListLength(LIST?pHead);
void?viewList(LIST?pHead);
void?deleteList(LIST?pHead,?int?pos);
int?main(){
int?i;
LIST?List?=?createList();
traverseList(?List?);
// for(i?=?1;??i?<=?11;?++i){
// deleteList(List,?1);
// traverseList(?List?);
// }
viewList(List);
return?0;
}
LIST?createList()?{
int?n,?i;
LIST?pNew,?pHead,?pTail;?//定義頭結(jié)點(diǎn),?尾結(jié)點(diǎn)?
pHead?=?(LIST)malloc(sizeof(LNode));
if(pHead?==?NULL){
exit(-1);
}
pTail?=?pHead;
printf("輸入人數(shù):?");
scanf("%d",?&n);
for(i?=?0;?i?<?n;?++i){
pNew?=?(LIST)malloc(sizeof(LNode));
if(pHead?==?NULL){
exit(-1);
}
pNew->data?=?i+1;
pTail->pNext?=?pNew;
pTail?=?pNew;//始終將新產(chǎn)生的結(jié)點(diǎn)作為尾結(jié)點(diǎn)?
}
pTail->pNext?=?pHead;
return?pHead;
}
void?traverseList(LIST?pHead){
LIST?p?=?pHead->pNext;
while(p?!=?pHead){
printf("%d?",?p->data);
p?=?p->pNext;?
}
printf("\n");
return?;
}
int??ListLength(LIST?pHead){
int?len?=?0;
LIST?p?=?pHead->pNext;
while(p?!=?pHead){
++len;
p?=?p->pNext;?
}
return?len;
}?
void?viewList(LIST?pHead){
int?i?=?1;
int?j?=?0;
int?cnt?=?1;?//作為計(jì)數(shù)
int?max;//最大上限
//首先鏈表不能為空
if(?pHead->pNext?==?pHead){
return?;?
}?
//最大上限不能為小于?0?的數(shù)?
printf("輸入報(bào)數(shù)最大上限為:?");
scanf("%d",?&max);
if(max?<=?0){
printf("輸入報(bào)數(shù)最大上限值有誤,程序終止!!!\n?");
exit(-1);
}
printf("\n");
//人員編號(hào)不能超過實(shí)有人數(shù)?&&?不能為負(fù)?
printf("輸入第一個(gè)報(bào)數(shù)的人員的編號(hào):?");
scanf("%d",?&j);
if(j?<?1?||?j?>?ListLength(pHead)){
printf("輸入第一個(gè)報(bào)數(shù)的人員的編號(hào)?有誤!!!\n?程序退出!");
exit(-1)?;?
}?
//?將?p?指向第一個(gè)報(bào)數(shù)的員工?
LIST?p?=?pHead->pNext;
LIST?pp?=?pHead;//pp?永遠(yuǎn)指向?p?指向的前面的那個(gè)結(jié)點(diǎn)?
LIST?q;?//作為臨時(shí)存儲(chǔ)?需刪除的結(jié)點(diǎn)?
while(p?!=?pHead){
if(i?==?j)
break;
p?=?p->pNext;
pp?=?pp->pNext;
? ++i;
}?
while(?ListLength(pHead)?!=?0){
if(?cnt?!=?max?)?{
p?=?p->pNext;
pp?=?pp->pNext?;
if(p?!=?pHead)
++cnt;
}?else?{
printf("%d?",?p->data);
q?=?p;
p?=?p->pNext;
pp->pNext?=?p;
free(q);
cnt?=?1;
}
} ?
}
//void?deleteList(LIST?pHead,int?i)?/*?改變pHead?*/
//{?/*?刪除pHead的第i個(gè)元素?*/
//??LIST?p=pHead->pNext,q;?/*?p指向頭結(jié)點(diǎn)?*/
//??int?j=0;
//??if(?i?<=?0?||?i?>?ListLength(pHead)?)?/*?第i個(gè)元素不存在?*/
//????return?;
//??while(?j?<?i-1)?/*?尋找第i-1個(gè)結(jié)點(diǎn)?*/
//??{
//????p?=?p->pNext;
//????j++;
//??}
//??q=p->pNext;?/*?q指向待刪除結(jié)點(diǎn)?*/
//??p->pNext=q->pNext;
//
//??if(pHead==q)?/*?刪除的是表尾元素?*/
//????pHead=p;
//??free(q);?/*?釋放待刪除結(jié)點(diǎn)?*/
//??return?;
//}
//void?deleteList(LIST?pHead,?int?pos){
//????int?i?=?0;
//????LIST?p,?q;
//????p?=?pHead;
//????if(?i?>?pos-1?&&?i?>?ListLength(pHead))
//????????return;
//????while(?p->pNext?!=?pHead?&&?i?<?pos-1?)?{
//????????p?=?p->pNext;
//????????++i;
//????}
//????
//????q?=?p->pNext;
//????p->pNext?=?q->pNext;
//????
//????if(pHead->pNext==q)?/*?刪除的是表尾元素?*/
//???? pHead=p;
//?? free(q);?/*?釋放待刪除結(jié)點(diǎn)?*/
//????
//????return;?
//}