for(循環)還是while(循環)循環之後,i和條件值相等。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}NODE,*PNODE;
PNODE createList(PNODE );
void travelList(PNODE);
void insertList(PNODE,int,int );
void delList(PNODE,int,int *);
bool isEmpty(PNODE);
int listLength(PNODE);
void sortList(PNODE);
void main()
{
PNODE phead=(PNODE)malloc(sizeof(NODE));
phead->next=NULL;
//創建單鏈表
phead=createList(phead);
//遍歷單鏈表
travelList(phead);
//插入結點至單鏈表中
printf("開始插入結點,請輸入要插入的數據");
int val;
scanf("%d",&val);
insertList(phead,3,val);
//遍歷單鏈表
travelList(phead);
//排序單鏈表
printf("開始排序\n");
sortList(phead);
//遍歷單鏈表
travelList(phead);
//從單鏈表中刪除結點
printf("開始刪除結點");
int val1;
delList(phead,2,&val1);
travelList(phead);
/*//遍歷單鏈表
travelList(phead);
//對單鏈表中元素進行排序
遍歷單鏈表
travelList(phead);*/
}
PNODE createList(PNODE phead)
{
//創建單鏈表方法有2種,一種頭插法,一種是尾插法。不管什麼方法都需要創造新的節點都要掛到頭結點上。
//你要造出一個結點,就得給結點賦值,創造一個賦值,2個賦值,多了,肯定要循環。你直接指定節點個數不就好了嗎
/*尾插法思想
PNODE ptail=phead;
printf("請輸入當前結點個數\n");
int len;
scanf("%d",&len);
for(int i=0;i<len;i++)
{
PNODE pnew=(PNODE)malloc(sizeof(NODE)*len);
if(NULL==pnew)
{
printf("內存分配失敗");
exit(-1);
}
else
{
printf("請給當前第%d個結點賦值",i+1);
int temp;
scanf("%d",&temp);
pnew->data=temp;
pnew->next=NULL;
}
phead->next=pnew;
phead=pnew;
}
return ptail;*/
//頭插法思想
printf("請輸入當前結點個數\n");
int len;
scanf("%d",&len);
for(int i=0;i<len;i++)
{
PNODE pnew=(PNODE)malloc(sizeof(NODE)*len);
if(NULL==pnew)
{
printf("內存分配失敗");
exit(-1);
}
else
{
printf("請給當前第%d個結點賦值",i+1);
int temp;
scanf("%d",&temp);
pnew->data=temp;
pnew->next=NULL;
pnew->next=phead->next;
phead->next=pnew;
}
}
return phead;
}
void travelList(PNODE phead)
{
PNODE p=phead->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
void insertList(PNODE phead,int pos,int val)
{
//最初的算法,可以實現,但是效率不高!
/*if(pos<1||pos>listLength(phead)+1)
{
printf("插入不合法,請重新插入");
return ;
}
PNODE pnew=(PNODE)malloc(sizeof(NODE));
pnew->data=val;
pnew->next=NULL;
//想插入結點,先找到其前面的一個結點。其實插入結點的時候,就是要將已經建立好的鏈表給弄斷了,弄斷了之後能不能接上問題。
// 只有找到前面的結點,能夠接上,如果你找後面,接不上,或者效率很低。
int i=0;
PNODE ptemp=phead;
while(i<pos-1)
{
ptemp=ptemp->next;
i++;
}
pnew->next=ptemp->next;
ptemp->next=pnew;*/
// 高效率算法來了,不用來計算鏈表長度.
//按位置找,按位置插入,就不用判斷鏈表的長度了。這種算法效率高些!
PNODE pnew=phead;
/*
這個方法只適用於不用循環的鏈表。
*/
PNODE p=phead;
int i=0;
//我不管你鏈表長度是多少,其實考慮問題無非有3:第一你這個鏈表存不存在(注意不是有沒有結點問題),第二,你插入位置合不合法,負數怎麼辦
//第三,你插入的位置,我鏈表的長度,夠不夠,我沒有那麼長,你非要在很大很大的長度上插入。
//方法是這樣解決的:我不管,順着找,先找到要插入位置的前面的那個結點。
while(NULL!=p&&i<pos-1)//去掉了鏈表存不存在的問題(注意光NULL!=p&&i<pos-1,解決不了循環鏈表的問題,結點p始終不等於NULL)
{
p=p->next;
i++;
}
if(i>pos-1||NULL==p) //判斷前方的那個結點是否存在,去掉了長度問題,去掉了鏈表合不合法的問題。
{
return;
}
//開始插入結點
PNODE pnew=(PNODE)malloc(sizeof(NODE));
pnew->next=NULL;
pnew->data=val;
pnew->next=p->next;
p->next=pnew;
}
int listLength(PNODE phead)
{
int i=0;
PNODE pnew=phead->next;
while(pnew!=NULL)
{
i++;
pnew=pnew->next;
}
return i;
}
bool isEmpty(PNODE phead)
{
if(phead->next==NULL)
return true;
else
return false;
}
void sortList(PNODE phead)
{
int temp;
int i,j;
PNODE pnew;
for(i=0;i<listLength(phead)-1;i++)
for(j=0,pnew=phead->next;j<listLength(phead)-1-i;j++,pnew=pnew->next)
{
if(pnew->data>pnew->next->data)
{
//交換數據。
temp=pnew->next->data;
pnew->next->data=pnew->data;
pnew->data=temp;
}
}
}
void delList(PNODE phead,int pos,int *val)
{
int i=0;
PNODE pnew=phead;
if(pos<1&&pnew==NULL)//這個地方都不用判斷爲空,效率高吧!
{
printf("對不起,無法刪除");
return;
}
for(i=0;i<pos-1&&pnew!=NULL;i++)
{
pnew=pnew->next;
}
PNODE q=pnew->next;
*val=pnew->next->data;
pnew->next=pnew->next->next;
printf("%d\n",*val);
free(q);
}