資料結構線性表的鏈式儲存結構(單連結串列)的表示及其基本操作

【花名柳隨風】發表於2020-10-31

標頭檔案 巨集定義 部分變數

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2 
#define ERROR 0
#define OK 1

typedef int Status;
typedef int Elemtype;
typedef struct LNode{
	Elemtype data;
	struct LNode * next;
}LNode,* LinkList;
Elemtype flag=0;//flag用於判斷連結串列是否初始化 0:未初始化 1:已初始化
Elemtype cflag=0;//cflag用於判斷連結串列是否為空 0:空  1:不空 

初始化一個空的連結串列

注:L是指向頭結點的指標(也叫頭指標,不知道什麼是頭結點,首元結點,好吧,簡要說下)
首元結點:是指連結串列中用來儲存資料元素的節點中的第一個節點
頭結點:指在連結串列的首元節點之前附設的一個結點,資料域內只放空表標 志和表長等資訊,也可以什麼都不放
什麼?為什麼要這樣設定?
這。。。。。。。
當然是因為這是前輩們的智慧嘍
單連結串列頭結點、首元節點詳解
嗯,為什麼形參定義是LinkList * L呢?
因為我們要改變頭指標的指向,分配一個大小是LNode的記憶體空間,讓頭指標指向它,如果不需要改變頭指標的指向,我們就只需要定義成LinkList L即可,然後讓頭結點的指標域為空,代表這是個空表,返回OK代表初始化成功。

Status InitList(LinkList * L)
{
	*L=(LinkList)malloc(sizeof(LNode));
	if(!*L))
	{
		exit(OVERFLOW);
	}
	(*L)->next=NULL;
	return OK;
} 

呼叫

case 1:
				printf("初始化或重置連結串列\n");
				printf("初始化請按1\n");
				printf("重置連結串列請按2\n");
				scanf("%d",&elem);
				if(elem==1)
				{				 
				  flag=InitList(&L);
				  if(flag==0)
				    printf("初始化失敗\n");
				  else
				    printf("初始化成功\n"); 	 
				} 
				if(elem==2)
				{
					if(flag==1)
					{
						cflag=ClearList(L);
					    printf("連結串列已清空\n");
					}else
					{
						printf("連結串列未初始化\n");
					}  					  
				}
				system("pause");
				break;

重置連結串列(清空連結串列)

使p指向首元結點,如果p不為空,進入迴圈,讓q指向p的後繼結點,然後釋放p所指向的 結點,p再移到下一個結點,q就像一個引路人,引著 p遍歷完連結串列,釋放所有的元素結點。當p指向尾結點進入迴圈後,q就為空,釋放p後,p=q ,p為空,不再執行迴圈,所有元素結點均被清空。令L的指標域為空,返回ERROR代表空表標誌

Status ClearList(LinkList L)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
	return ERROR;
}

呼叫

case 3:
			    if(flag!=0)
				{
					cflag=ClearList(L);
					printf("連結串列已清空\n");					
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

銷燬連結串列

遍歷,然後釋放每個結點所分配的空間。

Status DestroyList(LinkList * L) 
{
	LinkList p,q;
	p=(*L)->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	p=*L;
	free(p);
	return ERROR;	
}

呼叫

case 2:
				if(flag!=0)
				{
					printf("銷燬連結串列\n");
					flag=DestroyList(&L);
					printf("銷燬成功\n");
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

求連結串列的長度

定義一個計數器count,遍歷到每個結點時,count++;直到遍歷到最後一個結點,尾結點的指標域(為空)賦值給p,count+1;無法再次進行迴圈,返回count;

Status ListLength(LinkList L)
{
	Elemtype count=0;
	LinkList p;
	p=L->next;
	while(p)
	{
		p=p->next;
		count++;
	}
	return count; 
}

呼叫

case 4:
			    if(flag!=0)
				{
					printf("連結串列的長度為%d\n",ListLength(L));
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

求指定位置的元素值

定義一個指標p指向頭結點,當i=1時,p=p->next,指向第一個結點,當i=position時,指向所找的位置,返回該位置的資料域即可。

Status GetElem(LinkList L,Elemtype position)
{
	Elemtype i;
	LinkList p;
	p=L;
	for(i=1;i<=position;i++)
	{
		p=p->next;
	}
	return p->data;
} 

呼叫

case 5:
			    if(flag!=0)
				{
					printf("請輸入你所查詢的位置\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
	                {
	                   	printf("不存在這個位置\n");
					}else
					{
						elem=GetElem(L,position);
					    printf("該位置上的元素是%d\n",elem);
					}					
			    }else
				{
					printf("連結串列未初始化\n");
				} 
				system("pause");
				break;

求指定元素的位序

求位序,我們就要定義一個position,通過遍歷結點,找到與elem相等的位置,返回該位序。當position等於1時,p指向第一個結點,判斷,若不等,則指向第二個結點,position+1;直到找到position,返回position即可。

Status LocateElem(LinkList L,Elemtype elem)
{
	Elemtype position=1;
	LinkList p;
	p=L->next;
	while(p)
	{
		if(elem==p->data)
		   break;
		p=p->next;
		position++;   
	}
	return position;
}

呼叫

case 6:
			    if(flag!=0)
				{
					printf("請輸入你所查詢的元素\n");
					scanf("%d",&elem);
					position=LocateElem(L,elem);				
					if(position>ListLength(L))
					{
						printf("連結串列中不存在該元素\n");
					}else
				    {			    	
				    	printf("該元素在連結串列中的位置是%d\n",position);
					}
				}
				system("pause");
				break;

求輸入元素的直接前驅

定義指向節點的指標p,q;使P指向首元節點,判斷首元節點的資料域是否與elem相等,相等則結束呼叫,返回ERROR,若不相等則遍歷連結串列,使p指向要與elem相比較的節點,q指向p的前驅節點,若p->data=elem,結束迴圈,並返回q->data,如果elem不存在於連結串列中,p指向最後一個節點後,將會再次進入迴圈,最後一個節點的指標域(null)會賦值給p,結束迴圈,那麼,如果p==NULL,則代表連結串列中不存在elem

Status PriorElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	if(p->data==elem)
	   return ERROR;
	while(p)
	{
		q=p;
		p=p->next;
		if(p==NULL)
		  break;
		if(p->data==elem)
		   break;		   
	}
	if(p==NULL)
	  return ERROR;
	return q->data;   
} 

呼叫

case 7:
			    if(flag!=0)
				{
					printf("請輸入數字:\n");
					scanf("%d",&elem);
	                pelem=PriorElem(L,elem);
					if(pelem==ERROR)
					{
						printf("該元素不存在前驅或者不存在該元素\n");
					}else
					{
						printf("該元素的前驅是%d.\n",pelem);
					}    
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

求輸入元素的後繼

定義指向節點的指標p,q;使P指向首元節點,如果p!=null,則進入迴圈,令q始終指向p的後繼結點,判斷p->data是否等於elem, 若p->data=elem,結束迴圈,並返回q->data。如果elem是連結串列尾節點的資料域中的元素,則q==null(此時p指向最後一個節點), 如果連結串列中不存在elem,則p=null結束迴圈,返回ERROR

Status NextElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		if(p->data==elem)
		{
			break;
		}		   
		p=q;   
	}
	if(p==NULL||q==NULL)
	   return ERROR;
	return q->data;   
}

呼叫

case 8:
			    if(flag!=0)
				{
					printf("請輸入數字:\n");
					scanf("%d",&elem);
					nelem=NextElem(L,elem);
					if(nelem==ERROR)
					{
						printf("該元素不存在後繼或者不存在該元素\n");
					}else
					{
						printf("該元素的後繼是%d.\n",nelem);
					}	
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

插入元素

定義倆個可以指向節點的指標p,q,建立一個新的節點,使p指向新節點,將elem賦值給新節點的資料域,q指向頭結點,遍歷連結串列, 使q指向待插入位置的前驅節點,找到後,將插入位置的前驅節點的指標域賦值給新節點的指標域,然後將插入位置的前驅節點的指標域指向新節點

void ListInsert(LinkList L,Elemtype position,Elemtype elem) 
{
	Elemtype i;
	LinkList p,q;
	p=(LinkList)malloc(sizeof(LNode));
	p->data=elem;
	q=L;
	for(i=1;i<position;i++)//i=1時,q指向第一個節點,i=2時,q指向第二個節點
	{//所以當i=position-1時,q指向待插入位置的前驅節點 
		q=q->next;
	}
	p->next=q->next;
	q->next=p;	
}

呼叫

case 9:
			    if(flag!=0)
				{
					printf("請輸入你所要插入的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L)+1)
					{
						printf("位置錯誤\n");
					}else
					{
						printf("請輸入數字:\n");
						scanf("%d",&elem);
						ListInsert(L,position,elem);
						printf("插入成功\n");
					}						
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

刪除指定位置的元素

想要刪除某個節點,我們讓它的前驅節點的指標域指向其後繼節點,然後釋放要刪除的節點的空間即可
怎麼遍歷呢?定義一個變數i,記錄當前遍歷到的節點位置,直到遍歷到待刪除節點,進入迴圈,迴圈體語句結束
結束之後,q指向待刪除節點的前驅節點,p指向待刪除節點,i++,退出迴圈。

void ListDelete(LinkList L,Elemtype position)
{
	Elemtype i=1;
	LinkList p,q;
	p=L;
	while(p&&i<=position)
	{
		q=p;
		p=p->next;
		i++;
	} 
	q->next=p->next;
	free(p);
} 

呼叫

case 10:
			    if(flag!=0&&cflag==1)
				{
					printf("請輸入你所要刪除的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
					{
						printf("位置錯誤\n");
					}else
					{
						ListDelete(L,position);
						printf("刪除成功\n");
					}						
				}else
				{
					printf("連結串列未初始化或者連結串列為空\n");
				}
				system("pause");
				break;

輸出連結串列

依次遍歷每個結點,輸出其資料域即可。

void ListTraverse(LinkList L)
{
	LinkList p;
	p=L->next;
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
} 

呼叫

	case 11:
			    if(flag!=0)
				{
					printf("輸出連結串列\n");					
					ListTraverse(L);
					printf("輸出完成\n");	
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;

用頭插法輸入元素

定義倆個指向連結串列結點的指標,p用來儲存分配的大小為LNode空間的首地址,q用來給p指向的結點的指標域賦值(即上一次分配的結點的首地址),因為(頭插法)輸入的第一個元素為連結串列的尾結點,所以得將q初始化為null.儲存在尾結點的指標域內。如果輸入-1,代表結束輸入。
我們來看下迴圈體內的語句,首先,分配新空間,將首地址賦給p,判斷是否分配成功,成功後,使用者輸入數字,這時,在判斷數字是否為-1,是的話 就要釋放剛生成的空間,並退出迴圈。不是的話,將elem賦給新結點的資料域,將q賦給新結點的指標域之後,令q指向新結點,(記錄新結點的地址,為了讓下次迴圈生成的結點能連上上一次迴圈生成的結點),結束迴圈,將q的值賦值給頭結點,返回OK,代表元素錄入完成。

Status CreateList(LinkList L)
{
	LinkList p,q;
	q=NULL;
	Elemtype elem;
	while(1)
	{
		p=(LinkList)malloc(sizeof(LNode));
		if(!p)
		  exit(OVERFLOW);
		scanf("%d",&elem); 
		if(elem==-1)
		{
		    break;
		    free(p);
		}
		p->data=elem;
		p->next=q;
		q=p;		
	}
	L->next=q;
	return OK;
 }

呼叫

case 12:
				if(flag!=0)
				{
					printf("請輸入數字:\n");
					printf("如果輸入-1,代表結束\n");
					cflag=CreateList(L);					
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
			    break;	

逆置連結串列

定義指標p,q,p用來遍歷原連結串列,q用來儲存新結點的地址,並連線新連結串列。因為原連結串列有p指向,所以可以將頭指標L解放出來,令頭結點的指標域為空,作為新連結串列的頭指標。
while (p )代表 將原連結串列的結點依次遍歷,直到遍歷到尾結點,進入迴圈。
(第一次迴圈)分配新的結點,令q指向新結點,考慮異常情況後,將原連結串列的第一個結點的資料域賦值給新結點的指標域,(為了節省空間,我們仍用原連結串列的頭指標),將L->next賦值給新結點 的指標域(參考頭插法),將新結點的首地址q賦值給頭結點的指標域,p再指向原連結串列的下一個節點。
(第二次迴圈)依舊分配新的空間,將原連結串列第二個節點的資料域賦值給新結點的資料域,將上一個新結點的地址(即L->next)賦給新結點的指標域,然後用p->next指向新結點,p遍歷到原連結串列的下一個結點。

void NegaListTraverse(LinkList L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{		
		q=(LinkList)malloc(sizeof(LNode));
		if(!q)
		  exit(OVERFLOW);
		q->data=p->data;
		q->next=L->next;
		L->next=q;  
        p=p->next;
	}
}

呼叫

case 13:
				if(flag!=0)
				{
					printf("單連結串列的逆序排放\n");					
					NegaListTraverse(L);					
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
			    break;

完整程式碼

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2 
#define ERROR 0
#define OK 1

typedef int Status;
typedef int Elemtype;
typedef struct LNode{
	Elemtype data;
	struct LNode * next;
}LNode,* LinkList;
Elemtype flag=0;//flag用於判斷連結串列是否初始化 0:未初始化 1:已初始化
Elemtype cflag=0;//cflag用於判斷連結串列是否為空 0:空  1:不空 

Status InitList(LinkList * L);//初始化一個空的連結串列
Status ClearList(LinkList L);//重置連結串列 
Status DestroyList(LinkList * L);//銷燬連結串列
Status ListLength(LinkList L);//求連結串列的長度
Status GetElem(LinkList L,Elemtype position);//求指定位置的元素值 
Status LocateElem(LinkList L,Elemtype elem);//求指定元素的位序 
Status PriorElem(LinkList L,Elemtype elem);//求前驅 
Status NextElem(LinkList L,Elemtype elem);//求後繼
void ListInsert(LinkList L,Elemtype position,Elemtype elem);//插入節點  
void ListDelete(LinkList L,Elemtype elem);//刪除節點 
Status CreateList(LinkList L);//儲存元素
void ListTraverse(LinkList L);//遍歷連結串列
void NegaListTraverse(LinkList L);//逆置連結串列 
int main()
{
	Elemtype fun;//fun是使用者選擇的功能 
    Elemtype position;
    Elemtype elem;
    Elemtype pelem;//前驅 
    Elemtype nelem;//後繼  
	LinkList L=NULL;	
	while(1)
	{//while的左括號 
	    printf("輸出選單\n");
	    printf("1.初始化或重置連結串列\n");
	    printf("2.銷燬連結串列\n");
	    printf("3.清空連結串列\n");
    	printf("4.連結串列長度\n");
    	printf("5.指定位置的元素值\n");
    	printf("6.連結串列已存在元素的位序\n");
    	printf("7.求輸入元素的直接前驅\n");
    	printf("8.求輸入元素的直接後繼\n");
    	printf("9.在第i個位置插入一個元素\n");
    	printf("10.刪除第i個元素\n");
    	printf("11.輸出所有的連結串列元素\n");
    	printf("12.初始化並用頭插法(或尾插法)輸入元素\n");
    	printf("13.實現單連結串列的逆序存放\n");
		printf("請輸入數字選擇你所選擇的操作\n");
		printf("輸入負數退出程式\n");
		scanf("%d",&fun);
		if(fun<0)
		   break;	
		switch(fun)
		{//switch的左括號 
			case 1:
				printf("初始化或重置連結串列\n");
				printf("初始化請按1\n");
				printf("重置連結串列請按2\n");
				scanf("%d",&elem);
				if(elem==1)
				{				 
				  flag=InitList(&L);
				  if(flag==0)
				    printf("初始化失敗\n");
				  else
				    printf("初始化成功\n"); 	 
				} 
				if(elem==2)
				{
					if(flag==1)
					{
						cflag=ClearList(L);
					    printf("連結串列已清空\n");
					}else
					{
						printf("連結串列未初始化\n");
					}  					  
				}
				system("pause");
				break;
			case 2:
				if(flag!=0)
				{
					printf("銷燬連結串列\n");
					flag=DestroyList(&L);
					printf("銷燬成功\n");
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;
			case 3:
			    if(flag!=0)
				{
					cflag=ClearList(L);
					printf("連結串列已清空\n");					
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;
			case 4:
			    if(flag!=0)
				{
					printf("連結串列的長度為%d\n",ListLength(L));
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;
			case 5:
			    if(flag!=0)
				{
					printf("請輸入你所查詢的位置\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
	                {
	                   	printf("不存在這個位置\n");
					}else
					{
						elem=GetElem(L,position);
					    printf("該位置上的元素是%d\n",elem);
					}					
			    }else
				{
					printf("連結串列未初始化\n");
				} 
				system("pause");
				break;
			case 6:
			    if(flag!=0)
				{
					printf("請輸入你所查詢的元素\n");
					scanf("%d",&elem);
					position=LocateElem(L,elem);				
					if(position>ListLength(L))
					{
						printf("連結串列中不存在該元素\n");
					}else
				    {			    	
				    	printf("該元素在連結串列中的位置是%d\n",position);
					}
				}
				system("pause");
				break;
			case 7:
			    if(flag!=0)
				{
					printf("請輸入數字:\n");
					scanf("%d",&elem);
	                pelem=PriorElem(L,elem);
					if(pelem==ERROR)
					{
						printf("該元素不存在前驅或者不存在該元素\n");
					}else
					{
						printf("該元素的前驅是%d.\n",pelem);
					}    
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;
			case 8:
			    if(flag!=0)
				{
					printf("請輸入數字:\n");
					scanf("%d",&elem);
					nelem=NextElem(L,elem);
					if(nelem==ERROR)
					{
						printf("該元素不存在後繼或者不存在該元素\n");
					}else
					{
						printf("該元素的後繼是%d.\n",nelem);
					}	
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;
			case 9:
			    if(flag!=0)
				{
					printf("請輸入你所要插入的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L)+1)
					{
						printf("位置錯誤\n");
					}else
					{
						printf("請輸入數字:\n");
						scanf("%d",&elem);
						ListInsert(L,position,elem);
						printf("插入成功\n");
					}						
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;
			case 10:
			    if(flag!=0&&cflag==1)
				{
					printf("請輸入你所要刪除的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
					{
						printf("位置錯誤\n");
					}else
					{
						ListDelete(L,position);
						printf("刪除成功\n");
					}						
				}else
				{
					printf("連結串列未初始化或者連結串列為空\n");
				}
				system("pause");
				break;
			case 11:
			    if(flag!=0)
				{
					printf("輸出連結串列\n");					
					ListTraverse(L);
					printf("輸出完成\n");	
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
				break;						
			case 12:
				if(flag!=0)
				{
					printf("請輸入數字:\n");
					printf("如果輸入-1,代表結束\n");
					cflag=CreateList(L);					
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
			    break;		
			case 13:
				if(flag!=0)
				{
					printf("單連結串列的逆序排放\n");					
					NegaListTraverse(L);					
				}else
				{
					printf("連結串列未初始化\n");
				}
				system("pause");
			    break;						 
		}//switch的右括號
		system("cls");		
	}//while的右括號 
	return 0;
}
//初始化一個空的連結串列
Status InitList(LinkList * L)
{
	*L=(LinkList)malloc(sizeof(LNode));
	if(!*L)
	{
		exit(OVERFLOW);
	}
	(*L)->next=NULL;
	return OK;
} 
//重置連結串列
Status ClearList(LinkList L)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
	return ERROR;
}
//銷燬連結串列 
Status DestroyList(LinkList * L) 
{
	LinkList p,q;
	p=(*L)->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	p=*L;
	free(p);
	return ERROR;	
}
//求連結串列的長度
Status ListLength(LinkList L)
{
	Elemtype count=0;
	LinkList p;
	p=L->next;
	while(p)
	{
		p=p->next;
		count++;
	}
	return count; 
}
//求指定位置的元素值
Status GetElem(LinkList L,Elemtype position)
{
	Elemtype count=0;
	Elemtype i;
	LinkList p;
	p=L;
	for(i=1;i<=position;i++)
	{
		p=p->next;
	}
	return p->data;
} 
//求指定元素的位序
Status LocateElem(LinkList L,Elemtype elem)
{
	Elemtype position=1;
	LinkList p;
	p=L->next;
	while(p)
	{
		if(elem==p->data)
		   break;
		p=p->next;
		position++;   
	}
	return position;
} 
//求輸入元素的直接前驅
//定義指向節點的指標p,q;使P指向首元節點,判斷首元節點的資料域是否與elem相等,相等則結束呼叫,返回ERROR,若不相等則遍歷連結串列,使p指向要與elem相比較的節點,q指向
//p的前驅節點,若p->data==elem,結束迴圈,並返回q->data,如果elem不存在於連結串列中,p指向最後一個節點後,將會再次進入迴圈,最後一個節點的指標域(null)會賦值給p,
//結束迴圈,那麼,如果p==NULL,則代表連結串列中不存在elem 
Status PriorElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	if(p->data==elem)
	   return ERROR;
	while(p)
	{
		q=p;
		p=p->next;
		if(p==NULL)
		  break;
		if(p->data==elem)
		   break;		   
	}
	if(p==NULL)
	  return ERROR;
	return q->data;   
} 
//求輸入元素的後繼
//定義指向節點的指標p,q;使P指向首元節點,如果p!=null,則進入迴圈,令q始終指向p的後繼結點,判斷p->data是否等於elem, 若p->data==elem,結束迴圈,並返回q->data
//如果elem是連結串列尾節點的資料域中的元素,則q==null(此時p指向最後一個節點), 如果連結串列中不存在elem,則p==null
//結束迴圈,返回ERROR 
Status NextElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		if(p->data==elem)
		{
			break;
		}		   
		p=q;   
	}
	if(p==NULL||q==NULL)
	   return ERROR;
	return q->data;   
}
//插入元素
//定義倆個可以指向節點的指標p,q,建立一個新的節點,使p指向新節點,將elem賦值給新節點的資料域,q指向頭結點,遍歷連結串列, 
//使q指向待插入位置的前驅節點,找到後,將
//插入位置的前驅節點的指標域賦值給新節點的指標域,然後將插入位置的前驅節點的指標域指向新節點 
void ListInsert(LinkList L,Elemtype position,Elemtype elem) 
{
	Elemtype i;
	LinkList p,q;
	p=(LinkList)malloc(sizeof(LNode));
	p->data=elem;
	q=L;
	for(i=1;i<position;i++)//i=1時,q指向第一個節點,i=2時,q指向第二個節點
	{//所以當i=position-1時,q指向待插入位置的前驅節點 
		q=q->next;
	}
	p->next=q->next;
	q->next=p;	
}
//刪除指定位置的元素
/* 想要刪除某個節點,我們讓它的前驅節點的指標域指向其後繼節點,然後釋放要刪除的節點的空間即可
怎麼遍歷呢?定義一個變數i,記錄當前遍歷到的節點位置,直到遍歷到待刪除節點,進入迴圈,迴圈體語句結束
結束之後,q指向待刪除節點的前驅節點,p指向待刪除節點,i++,退出迴圈, 
*/
void ListDelete(LinkList L,Elemtype position)
{
	Elemtype i=1;
	LinkList p,q;
	p=L;
	while(p&&i<=position)
	{
		q=p;
		p=p->next;
		i++;
	} 
	q->next=p->next;
	free(p);
} 
//輸出連結串列
void ListTraverse(LinkList L)
{
	LinkList p;
	p=L->next;
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
} 
//用頭插法輸入元素
Status CreateList(LinkList L)
{
	LinkList p,q;
	q=NULL;
	Elemtype elem;
	while(1)
	{
		p=(LinkList)malloc(sizeof(LNode));
		if(!p)
		  exit(OVERFLOW);
		scanf("%d",&elem); 
		if(elem==-1)
		   break; 
		p->data=elem;
		p->next=q;
		q=p;		
	}
	L->next=q;
	return OK;
 } 
//逆置連結串列 
void NegaListTraverse(LinkList L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{		
		q=(LinkList)malloc(sizeof(LNode));
		if(!q)
		  exit(OVERFLOW);
		q->data=p->data;
		q->next=L->next;
		L->next=q;  
        p=p->next;
	}
}

OK,就到這裡,謝謝觀看,下次再會!
如果你發現了錯誤,請指正!!!

相關文章