單鏈表C語言操作
阿新 • • 發佈:2019-01-09
連結串列是一種相對於順序儲存空間而言的鏈式儲存結構,是一種在儲存空間而言不連續的一種資料結構。其中的每個元素稱為節點,包含有資料域和指標域,指標域儲存的是指向下一個節點,資料域代表這個元素的資料
struct ListNode
{
int data;
struct ListNode *next;
};
頭節點,存放第一個節點的地址,資料域一般設為0,最後一個節點的指標域一般設為NULL,沒有後繼節點。
- 建立一個單鏈表,先建立一個頭節點,然後用一個臨時節點去初始化連結串列中的元素
pNode CreateListnew() { int len;//連結串列長度 int val;//節點的數值 int i=0; //建立連結串列的頭部 頭節點不存放資料,指標指向第一個節點 pNode pHead=(pNode)malloc(sizeof(Node));//分配空間 if(pHead==NULL) { printf("malloc fail for header\r\n"); return NULL; } pHead->next=NULL;//頭節點指標域清空 pNode tmp=pHead;//臨時節點 初始是頭節點 for(i=0;i<Length;i++) { pNode pNew=(pNode)malloc(sizeof(Node));//分配空間 if(pNew==NULL) { printf("malloc fail for new node\r\n"); return NULL; } pNew->data=2*i;//新節點的資料域 tmp->next=pNew;//將pNew指向新節點插入連結串列 tmp=pNew;//將新節點賦給這個臨時節點,方便下一次插入 } tmp->next=NULL;//最後節點的指標域清空 printf("create list success\r\n"); return pHead; //f返回頭節點 }
- 單鏈表求長
設定當前指標P和一個計數器i,初始時P指向連結串列中的第一個結點,p每向下移動一個結點時,i就加1,直到到達p連結串列的尾部
//測試連結串列長度
int ListLength(pNode List)
{
pNode P=List->next;//傳參的是頭節點,開始P應該是指向第一個節點
int i=0;
while(P!=NULL)
{
i++;
P=P->next;
}
return i;
}
- 遍歷連結串列
和單鏈表求長類似
//遍歷
void TraverseList(pNode List)
{
pNode P=List->next;
printf("遍歷連結串列值為:\r\n");
if(P==NULL)
{
printf("list is null!\r\n");
}
while(P!=NULL)
{
printf("%d ",P->data);
P=P->next;
}
printf("\r\n");
}
- 連結串列的尾插
找到整個連結串列的尾節點,建立一個新節點,是這個節點指向尾節點的next,並將這個新節點的指標域設定成空。
void tail_insert(pNode List,int val)
{
pNode P=List;
while(P->next!=NULL)
{
P=P->next;
}
pNode Tmp=(pNode)malloc(sizeof(Node));
if(Tmp==NULL)
{
printf("malloc fail for Tmp");
return -1;
}
P->next=Tmp;
Tmp->data=val;
Tmp->next=NULL;
}
- 單鏈表的頭插
有新的結點就把此結點放在頭結點的後面。操作過程中只需要把頭節點的指標域賦給建立的新節點的指標域,也就是新節點的後繼是原來的第一個節點,然後讓新結點變為連結串列的第一個節點
void HeadInsert(pNode List,int val)
{
pNode P=List;//頭節點
pNode Tmp=(pNode)malloc(sizeof(Node));
if(Tmp==NULL)
{
printf("malloc fail for Tmp");
return ;
}
Tmp->next=P->next;//頭節點的指標域賦給建立的節點的指標域
Tmp->data=val;
P->next=Tmp; // 讓新結點變為連結串列的第一個節點
}
- 連結串列中間插入
首先根據輸入連結串列的插入索引獲取要插入節點的前一個節點,建立一個新節點,前一個節點的指標域賦給這個新節點的指標域,並讓前一個節點的指標域指向這個新建立的節點。
void InsertList(pNode List,int pos,int val)
{
pNode P=List;
int position=0;
//尋找pos節點的前驅節點
while(P!=NULL&&position<pos-1)
{
P=P->next;
position++;
}
pNode Tmp=(pNode)malloc(sizeof(Node));
if(Tmp==NULL)
{
printf("malloc fail for Tmp");
return ;
}
//insert node
Tmp->data=val;
Tmp->next=P->next;
P->next=Tmp;
}
- 單鏈表的刪除
首先根據輸入連結串列的刪除索引獲取要刪除節點的前一個節點,建立一個新節點,前一個節點的指標域賦給這個新節點,並讓新建立的節點的指標域指向前一個節點的指標域。
void DeleteList(pNode List,int pos)
{
int position=0;
pNode P=List;
//尋找pos節點的前驅節點
while(P!=NULL&&position<pos-1)
{
P=P->next;
position++;
}
pNode Tmp=P->next;
P->next=Tmp->next;
free(Tmp);
Tmp=NULL;
}
下面是一個綜合例子,使用頭插法建立一個連結串列,開始時建立了10個元素,然後可以使用上面的一些單鏈表的函式對這個連結串列進行插入,刪除和遍歷
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Length 10
struct ListNode
{
int data;
struct ListNode *next;
};
typedef struct ListNode Node;
typedef struct ListNode* pNode;
//typedef Node* pNode;
//連結串列初始化
void ListInit(pNode List)
{
List=(pNode)malloc(sizeof(Node));//分配空間
if(List==NULL)
{
printf("malloc fail\r\n");
return;
}
List->next=NULL;
}
//建立單鏈表
pNode CreateList()
{
int len;//連結串列長度
int val;//節點的數值
int i=0;
//建立連結串列的頭部 頭節點不存放資料,指標指向第一個節點
pNode pHead=(pNode)malloc(sizeof(Node));//分配空間
if(pHead==NULL)
{
printf("malloc fail for header\r\n");
return NULL;
}
//建立連結串列的尾部 初始指向頭部 並將指標域置位空
pNode pTail=pHead;
pTail->next=NULL;
for(i=0;i<Length;i++)
{
pNode pNew=(pNode)malloc(sizeof(Node));//分配空間
if(pNew==NULL)
{
printf("malloc fail for new node\r\n");
return NULL;
}
pNew->data=2*i;
pTail->next=pNew; //末尾節點指標指向下一個新資料
pNew->next=NULL;
pTail=pNew; //將新節點複製給末尾節點
}
printf("create list success\r\n");
return pHead;
}
//建立單鏈表
pNode CreateListnew()
{
int len;//連結串列長度
int val;//節點的數值
int i=0;
//建立連結串列的頭部 頭節點不存放資料,指標指向第一個節點
pNode pHead=(pNode)malloc(sizeof(Node));//分配空間
if(pHead==NULL)
{
printf("malloc fail for header\r\n");
return NULL;
}
pHead->next=NULL;//頭節點指標域清空
pNode tmp=pHead;
for(i=0;i<Length;i++)
{
pNode pNew=(pNode)malloc(sizeof(Node));//分配空間
if(pNew==NULL)
{
printf("malloc fail for new node\r\n");
return NULL;
}
pNew->data=2*i;
tmp->next=pNew;//將pNew指向新節點插入連結串列
//pTail->next=pNew; //末尾節點指標指向下一個新資料
//pNew->next=NULL;
//pTail=pNew; //將新節點複製給末尾節點
tmp=pNew;//將新節點賦給這個臨時節點,方便下一次插入
}
tmp->next=NULL;//最後節點的指標域清空
printf("create list success\r\n");
return pHead;
}
//測試連結串列長度
int ListLength(pNode List)
{
pNode P=List->next;
int i=0;
while(P!=NULL)
{
i++;
P=P->next;
}
return i;
}
//遍歷
void TraverseList(pNode List)
{
pNode P=List->next;
printf("遍歷連結串列值為:\r\n");
if(P==NULL)
{
printf("list is null!\r\n");
}
while(P!=NULL)
{
printf("%d ",P->data);
P=P->next;
}
printf("\r\n");
}
//查詢
pNode FindList(pNode List)
{
pNode P=List->next;
int num=0;
int val=0;
printf("input your val");
scanf("%d",&val);
while((P!=NULL)&&(P->data)!=val)
{
P=P->next;
num++;
}
if(P!=NULL)
printf("找到節點:%d",num+1);
else
printf("找不到對應的節點");
printf("\r\n");
return P;
}
void InsertList(pNode List,int pos,int val)
{
pNode P=List;
int position=0;
//尋找pos節點的前驅節點
while(P!=NULL&&position<pos-1)
{
P=P->next;
position++;
}
pNode Tmp=(pNode)malloc(sizeof(Node));
if(Tmp==NULL)
{
printf("malloc fail for Tmp");
return ;
}
//insert node
Tmp->data=val;
Tmp->next=P->next;
P->next=Tmp;
}
//頭插 有新的結點就把此結點放在頭結點的後面
void HeadInsert(pNode List,int val)
{
pNode P=List;//頭節點
pNode Tmp=(pNode)malloc(sizeof(Node));
if(Tmp==NULL)
{
printf("malloc fail for Tmp");
return ;
}
Tmp->next=P->next;//頭節點的指標域賦給建立的節點的指標域
Tmp->data=val;
P->next=Tmp; // 讓新結點變為連結串列的第一個節點
}
void tail_insert(pNode List,int val)
{
pNode P=List;
while(P->next!=NULL)
{ // 讓新結點變為連結串列的第一個節點
P=P->next;
}
pNode Tmp=(pNode)malloc(sizeof(Node));
if(Tmp==NULL)
{
printf("malloc fail for Tmp");
return ;
}
P->next=Tmp;
Tmp->data=val;
Tmp->next=NULL;
}
void DeleteList(pNode List,int pos)
{
int position=0;
pNode P=List;
//尋找pos節點的前驅節點
while(P!=NULL&&position<pos-1)
{
P=P->next;
position++;
}
pNode Tmp=P->next;
P->next=Tmp->next;
free(Tmp);
Tmp=NULL;
}
int main()
{
//pNode List=CreateList();
pNode List=CreateListnew();//建立10個元素的節點並返回頭節點
TraverseList(List);
printf("List Length:%d\r\n",ListLength(List));
//FindList(List);
InsertList(List,3,50);//指定位置插入
TraverseList(List);//遍歷
printf("List Length:%d\r\n",ListLength(List));
DeleteList(List,3);//刪除元素
TraverseList(List);//遍歷
tail_insert(List,999);//尾插
TraverseList(List);//遍歷
HeadInsert(List,11);//頭插
TraverseList(List);//遍歷
printf("List Length:%d\r\n",ListLength(List));
return 0;
}