亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++中單鏈表的建立與基本操作

2020-01-26 15:44:56
字體:
來源:轉載
供稿:網友

準備數據

準備在鏈表操作中需要用到的變量及數據結構

示例代碼如下:

復制代碼 代碼如下:

struct Data   //數據結點類型
{
 string key;  //關鍵字
 string name;
 int age;
};
struct CLType  //定義鏈表結構
{
 Data nodeData;
 Data *nextNode;
};

定義了鏈表數據元素的類型Data以及鏈表的數據結構CLType。結點的具體數據保存在一個結構Data中,而指針nextNode用來指向下一個結點。

我們可以認為,該鏈表是一個班級學生的記錄,其中key表示學號,name為學生的名字,age為年齡。

追加結點

追加結點就是在鏈表末尾增加一個結點。表尾結點的地址部分原來保存的是空地址NULL,此時需要將其設置為新增結點的地址(即原表尾結點指向新增結點),然后將新增節點的地址部分設置為空地址NULL,即新增結點為表尾。

由于一般情況下,鏈表只有一個頭指針head,要在末尾添加結點就需要從頭指針head開始逐個檢查,直到找到最后一個結點(即表尾)。

追加結點的操作步驟如下:

(1)首先分配內存地址,保存新增結點。

(2)從頭指針head開始逐個檢查,直到找到最后一個結點(即表尾)。

(3)將表尾結點的地址設置為新增結點的地址。

(4)將新增結點的地址部分設置為空地址NULL,即新增結點成為表尾。

示例代碼如下:

復制代碼 代碼如下:

CLType * CLAddEnd(CLType *head,Data nodeData)
{
 CLType *node,*htemp;
 if(!(node = new CLType))
 {
  cout<<"分配內存失?。?<<endl;  //分配內存失敗
  return NULL;
 }
 else
 {
  node->nodeData = nodeData;   //保存結點數據
  node->nextNode = NULL;     //設置結點指針為空,即作為表尾
  if(head == NULL)      //當鏈表是空表的時候
  {
   head = node;
   return head;
  }
  htemp = head;
  while(htemp->nextNode != NULL)   //查找鏈表的末尾
  {
   htemp = htemp->nextNode; 
  }
  htemp->nextNode = node;
  return head;
 }

}

輸入參數head為鏈表頭指針,輸入參數nodeData為結點保存的數據。程序中,使用new關鍵字申請動態空間,如果內分配成功,node中將保存指向該內存區域的指針。

然后,將傳入的nodeData保存到申請的內存區域,并設置該結點指向下一結點的指針值為NULL。

插入頭結點

插入頭結點就是在鏈表首部添加結點的過程,和在表尾插入結點相反,這個操作是在表頭上插入結點,作為頭結點。

插入頭結點的步驟如下:

(1)首先分配內存,保存新增的結點。

(2)使新增姐弟那指向頭指針head所指向的結點

(3)然后使頭指針head指向新增結點

示例代碼如下:

復制代碼 代碼如下:

CLType *CLAddFirst(CLType *head,Data nodeData)
{
 CLType *node;
 if(!(node = new CLType))
 {
  cout<<"分配內存失敗"<<endl;
  return NULL;
 }
 else
 {
  node->nodeData = nodeData;  //保存結點數據
  node->nextNode = head;  //指向頭指針所指向的指針
  head = node;   //頭指針指向新增結點
  return head;
 }
}

輸入參數head為鏈表頭指針,輸入參數nodeData為結點中保存的數據。程序中首先使用new關鍵字申請一個新的保存結點的內存空間,如果申請成功,node中將保存指向該內存區域的指針。

然后,將傳入的nodeData保存到申請的內存區域中,并使新增的結點指向頭指針head所指向的結點,然后設置頭指針head重新指向新增結點。

查找結點

查找結點就是在鏈表結構中查找需要的元素。對于鏈表結構來說,一般可以分為按照結點序號查找和按照關鍵字查詢兩類。

按照結點序號查詢

即查詢鏈表中的第多少個結點,其示例代碼如下:

復制代碼 代碼如下:

CLType *CLFindNodeNum(CLType *head,int k)
{
 CLType *htemp;
 int i = 1;
 htemp = head;      //保存鏈表頭指針
          for(i = 1;i<k&&htemp;i++)     //找到該結點
          {
        htemp = htemp->nextNode;
         }
          return htemp;      //返回指向第k個結點的指針
}

輸入參數head為鏈表頭指針,輸入參數k為要查詢的結點的序號。通過序號進行多次循環,獲得指向該結點的指針,然后返回指針。

按照關鍵字查詢

即根據鏈表中結點的某一個關鍵字進行查詢,我們以查詢學生的姓名(name)為例,其示例代碼如下:

復制代碼 代碼如下:

CLType *CLFindNodeKey(CLType *head,string name)
{
 CLType * htemp;
 htemp = head;       //保存鏈表頭指針
 while(htemp)
 {
  if(htemp->nodeData.name == name) //當結點關鍵字和傳入關鍵字相同
  {
   return htemp;    //返回該結點指針
  }
  htemp = htemp->nextNode;
 }
 return NULL;
}

輸入參數head為鏈表頭指針,輸入參數name為要查詢的同學的姓名。遍歷查詢所有的同學的姓名,當有結點的姓名與所查詢的姓名相同的時候,則返回該結點的指針。

插入結點

插入結點就是在鏈表中間部分的位置增加一個結點。

插入結點的步驟如下:

(1)分配內存空間,保存新增的結點。

(2)找到要插入的邏輯位置,也就是找到插在那個結點的后面。

(3)修改插入位置結點的指針,使其指向新增結點,而使新增結點指向原插入位置所指向的結點。

示例代碼如下:

復制代碼 代碼如下:

CLType *CLInsertNode(CLType *head,int k,Data nodeData)
{
 CLType *node,*nodetemp;
 if(!(node = new CLType))    //申請結點
 {
  cout<<"申請內存失敗"<<endl;
  return NULL;
 }
 else
 {
  node->nodeData = nodeData;  //保存結點中的數據
  nodetemp=CLFindNodeNum(head,k-1);//通過按照結點序號查找函數找到插入點前一個結點(關鍵結點)
  if(nodetemp)
  {
   node->nextNode = nodetemp->nextNode;//插入的結點指向關鍵結點的下一個節點
   nodetemp->nextNode = node;    //關鍵結點指向插入點
  }
  else
  {
   cout<<"沒有找到正確的插入位置"<<endl;
   delete node;
  }
 }
 return head;      //返回頭指針
}

輸入參數head為鏈表頭指針,輸入參數findkey為鏈表中進行查找的結點關鍵字,找到該結點后將在該結點后面添加結點數據,nodeData為新增結點的數據。程序中首先使用new申請結點空間,然后調用CLFindNodeNum函數查找指向結點,然后執行插入操作。

刪除結點

刪除結點就是將鏈表中的某個結點數據刪除,并不影響其位置前后的結點。

刪除結點操作的步驟如下:

(1)查找需要刪除的結點。

(2)使前一結點指向當前節點的下一結點。

(3)刪除該結點

刪除結點可以通過結點的序號確定要刪除的結點,當然也可以通過結點的關鍵字確定要刪除的結點。

我們以通過關鍵字刪除結點為例,示例代碼如下:

復制代碼 代碼如下:

int CLDeleteNode(CLType *head,string name)
{
 CLType *node,*htemp;    //node用于刪除結點的前一個結點
 htemp = head;
 node =  head;
 while(htemp)
 {
  if(htemp->nodeData.name == name)//找到關鍵字,執行刪除操作
  {
   node->nextNode = htemp->nextNode;//使前一結點指向當前節點的下一結點
   delete htemp;     //釋放該結點的空間(即,刪除了結點)
   return 1;
  }
  else
  {
   node = htemp;     //指向當前節點
   htemp = htemp->nextNode;  //指向下一個結點
  }
 }
  return 0;        //刪除失敗
}

head為鏈表頭指針,輸入參數name表示要刪除的同學的姓名。程序中,通過一個循環,按關鍵字在整個鏈表中查找要刪除的結點。如果找到被刪除的結點,則設置上一結點(node指針所指結點)指向當前結點(h指針所指結點)的下一個結點,即在邏輯上將該結點刪除,然后對該結點執行delete操作,釋放結點占用的內存空間,即在物理上將其刪除。

計算鏈表長度

計算鏈表長度也就是統計鏈表中結點的數量。順序表中計算鏈表長度比較方便,但在鏈表中鏈表的長度卻需要通過遍歷鏈表來獲得,因為鏈表在物理上不是連續存儲的。

示例代碼如下:

復制代碼 代碼如下:

int CLLength(CLType *head)
{
 CLType *htemp;
 int Len = 0;
 htemp = head;
 while(htemp)       //遍歷整個數組
 {
  Len++;        //累加結點的數量
  htemp = htemp->nextNode;    //處理下一個結點
 }
 return Len;
}

參數head是鏈表的頭指針,程序中通過while來遍歷指針,Len作為計數器,通過記錄循環的次數,來獲得鏈表的長度,當指針為NULL時截止,然后返回計數器的值。

顯示所有結點

遍歷所有的結點,并輸出。

復制代碼 代碼如下:

void CLAllNode(CLType *head)
{
 CLType *htemp;
 htemp = head;
 while(htemp)       //遍歷整個數組
 {
  nodeData = htemp->nodeData;   //獲取結點數據
  cout<<"key:"<<nodeData.key<<",name:"<<nodeData.name<<",age:"<<nodeData.age<<endl;
  htemp = htemp->nextNode;    //處理下一個結點
 }
}

輸出結點的函數,沒有返回值,所有定義為void。每次都通過CLType類型的結點獲得其nodeData的值

鏈表操作完整示例

完整示例的代碼比較長,要耐心看哈……  :)

復制代碼 代碼如下:

#include<iostream>
#include<string>
using namespace std;
struct Data   //數據結點類型
{
 string key;  //關鍵字
 string name;
 int age;
};
struct CLType          //定義鏈表結構
{
 Data nodeData;
 CLType *nextNode;
};
CLType * CLAddEnd(CLType *head,Data nodeData)
{
 CLType *node,*htemp;
 if(!(node = new CLType))
 {
  cout<<"分配內存失敗!"<<endl;  //分配內存失敗
  return NULL;
 }
 else
 {
  node->nodeData = nodeData;         //保存結點數據
  node->nextNode = NULL;   //設置結點指針為空,即作為表尾
  if(head == NULL)   //當鏈表是空表的時候
  {
   head = node;
   return head;
  }
  htemp = head;
  while(htemp->nextNode != NULL) //查找鏈表的末尾
  {
   htemp = htemp->nextNode; 
  }
  htemp->nextNode = node;
  return head;
 }

}
CLType *CLAddFirst(CLType *head,Data nodeData)
{
 CLType *node;
 if(!(node = new CLType))
 {
  cout<<"分配內存失敗"<<endl;
  return NULL;
 }
 else
 {
  node->nodeData = nodeData;  //保存結點數據
  node->nextNode = head;  //指向頭指針所指向的指針
  head = node;   //頭指針指向新增結點
  return head;
 }
}
CLType *CLFindNodeNum(CLType *head,int k)
{
 CLType *htemp;
 int i = 1;
 htemp = head;    //保存鏈表頭指針
    for(i = 1;i<k&&htemp;i++)   //找到該結點
    {
     htemp = htemp->nextNode;
    }
    return htemp;     //返回指向第k個結點的指針
}
CLType *CLFindNodeName(CLType *head,string name)
{
 CLType * htemp;
 htemp = head;    //保存鏈表頭指針
 while(htemp)
 {
  if(htemp->nodeData.name == name) //當結點關鍵字和傳入關鍵字相同
  {
   return htemp;  //返回該結點指針
  }
  htemp = htemp->nextNode;
 }
 return NULL;
}
CLType *CLInsertNode(CLType *head,int k,Data nodeData)
{
 CLType *node,*nodetemp;
 if(!(node = new CLType))   //申請結點
 {
  cout<<"申請內存失敗"<<endl;
  return NULL;
 }
 else
 {
  node->nodeData = nodeData;  //保存結點中的數據
  nodetemp=CLFindNodeNum(head,k-1);    //通過按照結點序號查找函數找到插入點前一個結點(關鍵結點)
  if(nodetemp)
  {
   node->nextNode = nodetemp->nextNode;  //插入的結點指向關鍵結點的下一個節點
   nodetemp->nextNode = node;    //關鍵結點指向插入點
  }
  else
  {
   cout<<"沒有找到正確的插入位置"<<endl;
   delete node;
  }
 }
 return head;      //返回頭指針
}
int CLDeleteNode(CLType *head,string name)
{
 CLType *node,*htemp;    //node用于刪除結點的前一個結點
 htemp = head;
 node =  head;
 while(htemp)
 {
  if(htemp->nodeData.name == name)             //找到關鍵字,執行刪除操作
  {
   node->nextNode = htemp->nextNode;  //使前一結點指向當前節點的下一結點
   delete htemp;   //釋放該結點的空間(即,刪除了結點)
   return 1;
  }
  else
  {
   node = htemp;   //指向當前節點
   htemp = htemp->nextNode;  //指向下一個結點
  }
 }
  return 0;     //刪除失敗
}
int CLLength(CLType *head)
{
 CLType *htemp;
 int Len = 0;
 htemp = head;
 while(htemp)     //遍歷整個數組
 {
  Len++;     //累加結點的數量
  htemp = htemp->nextNode;    //處理下一個結點
 }
 return Len;
}
void CLAllNode(CLType *head)
{
 CLType *htemp;
 Data nodeData;
 htemp = head;
 cout<<"鏈表長度為:"<<CLLength(head)<<endl;
 while(htemp)     //遍歷整個數組
 {
  nodeData = htemp->nodeData;   //獲取結點數據
  cout<<"key:"<<nodeData.key<<",name:"<<nodeData.name<<",age:"<<nodeData.age<<endl;
  htemp = htemp->nextNode;    //處理下一個結點
 }
}
int main()
{
 CLType *node,*head = NULL;
 Data nodeData;
 string name;
 int k;
 cout<<"請先輸入鏈表中的數據,格式為:學號,姓名,年齡(年齡為0時停止輸入)"<<endl;
 while(1)
 {
  cin>>nodeData.key>>nodeData.name>>nodeData.age;
  if(nodeData.age==0)break;
  head=CLAddEnd(head,nodeData);  //在鏈表的尾部添加結點
 }
 CLAllNode(head);     //顯示所有的結點
 //演示在頭部插入數據
 cout<<"請輸入一個結點,并在鏈表的頭部插入"<<endl;
 cin>>nodeData.key>>nodeData.name>>nodeData.age;
 head=CLAddFirst(head,nodeData);
 CLAllNode(head);
 //演示在中間位置插入一個數據
 cout<<"請輸入一個在鏈表內部插入的結點:"<<endl;
 cin>>nodeData.key>>nodeData.name>>nodeData.age;
 cout<<"請輸入插入點的位置:";
 cin>>k;
 head=CLInsertNode(head,k,nodeData);
 CLAllNode(head); 
 //演示按照序號查詢數據
 cout<<"請輸入按照結點查詢的一個結點序號:";
 cin>>k;
 node=CLFindNodeNum(head,k);
 cout<<"您所查詢的結點是:"<<endl;
 cout<<"key:"<<node->nodeData.key<<",name:"<<node->nodeData.name<<",age:"<<node->nodeData.age<<endl;
 //演示按照姓名查詢數據
 cout<<"請輸入一個按照姓名查詢的一個同學的姓名:";
 cin>>name;
 node=CLFindNodeName(head,name);
 cout<<"您所查詢的結點是:"<<endl;
 cout<<"key:"<<node->nodeData.key<<",name:"<<node->nodeData.name<<",age:"<<node->nodeData.age<<endl;
 //演示刪除數據信息
 cout<<"請輸入結點中的一個同學中的名字,系統會刪除他的信息:";
 cin>>name;
 if(CLDeleteNode(head,name))cout<<"數據刪除成功!"<<endl;
 CLAllNode(head);
 return 0;
}

程序運行結果示例:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
海角国产乱辈乱精品视频| 久久精品夜夜夜夜夜久久| 亚洲自拍偷拍区| 国产美女久久精品香蕉69| 日韩一二三在线视频播| 国产日产久久高清欧美一区| 欧美性猛交99久久久久99按摩| 欧美猛少妇色xxxxx| 国产精品亚洲网站| 欧美一区二三区| 久久亚洲成人精品| 欧美在线视频免费播放| 欧美色xxxx| 久久精品国产96久久久香蕉| 日韩精品在线观看视频| 欧美高跟鞋交xxxxhd| 中文字幕亚洲情99在线| 欧美一区二区三区艳史| 国产99视频精品免视看7| 国产精品高清网站| 国产成人中文字幕| 91免费人成网站在线观看18| 丰满岳妇乱一区二区三区| 精品视频在线播放| 久久在线视频在线| 欧美色图在线视频| 亚洲片国产一区一级在线观看| 日本精品一区二区三区在线播放视频| 在线观看国产成人av片| 亚洲欧洲一区二区三区在线观看| 日韩在线免费高清视频| 欧美激情女人20p| 久久久久久国产| 亚洲福利精品在线| 性色av一区二区三区免费| 亚洲激情国产精品| 亚洲xxxx妇黄裸体| 中文字幕不卡在线视频极品| 欧美激情奇米色| 欧美日韩国产色视频| 亚洲色图50p| 亚洲国产天堂久久综合| 2020国产精品视频| 欧美成人黄色小视频| 伊人久久免费视频| 国产精品久久久久久五月尺| 久久99青青精品免费观看| 欧美午夜性色大片在线观看| 欧美激情成人在线视频| 超碰97人人做人人爱少妇| 懂色aⅴ精品一区二区三区蜜月| 日韩亚洲欧美成人| 欧美国产日韩一区二区在线观看| 亚洲欧洲午夜一线一品| 国产欧美日韩专区发布| 国产精品视频区| 国产做受高潮69| 国产精品永久免费观看| 亚洲精品国产精品自产a区红杏吧| 国产一区二区三区高清在线观看| 亚洲国产小视频| 一区二区福利视频| 日韩精品免费在线观看| 亚洲国产另类久久精品| 九九热r在线视频精品| 国精产品一区一区三区有限在线| 性欧美xxxx视频在线观看| 尤物yw午夜国产精品视频明星| 欧美性猛交丰臀xxxxx网站| 在线观看欧美成人| 欧美日韩精品在线观看| 久久综合久中文字幕青草| 亚洲天堂av在线播放| 欧美成aaa人片在线观看蜜臀| 在线观看精品国产视频| 国产日韩精品入口| 国产精品专区第二| 亚洲综合第一页| 久久福利视频网| 91精品国产高清| 久热精品视频在线观看一区| 日韩一区视频在线| 欧美最猛性xxxxx(亚洲精品)| 欧美午夜片在线免费观看| 国产亚洲精品久久| 欧美精品在线免费播放| 国产精品一香蕉国产线看观看| 伊人久久综合97精品| 国产欧美久久久久久| 97在线观看视频国产| 91精品国产99久久久久久| 91av视频在线免费观看| 95av在线视频| 久久精品国产欧美亚洲人人爽| 精品国产91久久久| 国外成人在线视频| 日本高清+成人网在线观看| 日韩美女激情视频| 日韩精品视频在线播放| 日韩国产精品一区| 热久久美女精品天天吊色| 久久久久99精品久久久久| 国产精品亚洲欧美导航| 精品一区二区三区四区在线| 日韩美女写真福利在线观看| www.欧美免费| 视频直播国产精品| 色播久久人人爽人人爽人人片视av| 亚洲成人av在线| 国产成人拍精品视频午夜网站| 久久久999国产精品| 亚洲自拍欧美色图| 欧美激情视频三区| 日韩av电影免费观看高清| 一区二区三区美女xx视频| 国产三级精品网站| 中文欧美日本在线资源| 国产女同一区二区| 亚洲变态欧美另类捆绑| 最近2019中文字幕在线高清| 91热福利电影| 久久久欧美一区二区| 日韩av第一页| 精品动漫一区二区| 久久综合亚洲社区| 欧美日韩国产精品专区| 日本精品久久中文字幕佐佐木| 成人有码视频在线播放| 日韩有码在线播放| 日韩中文视频免费在线观看| 日韩有码在线播放| 亚洲国产精品久久久久久| 久久97久久97精品免视看| 亚州欧美日韩中文视频| 亚洲欧美国产精品| 永久免费精品影视网站| 欧美黑人国产人伦爽爽爽| 日韩精品在线视频| 亚洲精品久久久久久久久久久| 久久精品国产一区二区三区| 国产精品成人aaaaa网站| 国产精品免费福利| 欧美资源在线观看| 成人欧美一区二区三区黑人孕妇| 亚洲精品国产精品国产自| www.亚洲成人| 亚洲精品色婷婷福利天堂| 欧美一级电影在线| 亚洲综合中文字幕在线| 国产九九精品视频| 欧美一级视频在线观看| 亚洲性线免费观看视频成熟| 欧美一级大胆视频| 亚洲mm色国产网站| 欧美午夜激情小视频| 最新日韩中文字幕| 国内精品视频一区| 精品亚洲夜色av98在线观看| 欧美精品videos| 高清在线视频日韩欧美| 亚洲精品一二区| 国产精品永久免费观看| 亚洲最大av网| 久久精品成人一区二区三区|