線性表之單鏈表實現


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);


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章