C++資料結構雙鏈表
《資料結構》實驗二:
線性表綜合實驗
一.實驗目的
鞏固線性表的資料結構的儲存方法和相關操作,學會針對具體應用,使用線性表的相關知識來解決具體問題,鞏固課堂學習。
二. 實驗內容
1.建立一個由n個學生成績的順序表,n的大小由自己確定,每一個學生的成績資訊由自己確定,實現資料的對錶進行插入、刪除、查詢等操作。分別輸出結果。
這裡用雙鏈表來實現。
//
// main.cpp
// 雙鏈表
//
// Created by 樑華建 on 2017/9/17.
// Copyright © 2017年 樑華建. All rights reserved.
//
#include <iostream>
template<class DataType>
struct DulNode
{
DataType data;
DulNode<DataType> *prior,*next;
};
template<class DataType>
class LinkList
{
public :
LinkList(); //無參建構函式,建立只有頭結點的雙鏈表
LinkList(DataType a[],int n); //有參建構函式,建立有n個元素的雙鏈表
~LinkList();
int Length(); //求雙鏈表的長度
DataType Get(int i); //按位置查詢,在雙鏈表中查詢到第i個節點的袁術
int locate(DataType x); //按位置查詢,在雙鏈表中查詢到值為x的元素
void Insert(int i ,DataType x);//插入操作,在第i個位置插入元素值為x的元素
DataType Delete(int i); //刪除在第i個位置的元素
void PrintList(); //遍歷輸出所有雙鏈表的函式
private :
DulNode<DataType >*first; //雙鏈表的頭指標
};
//遍歷函式
template<class DataType>
void LinkList<DataType>::PrintList()
{
DulNode<DataType> * p=NULL; //建立工作結點
p=first->next;
while (p!=NULL) {
std::cout<<p->data<<" "; //遍歷輸出所有元素直到尾部
p=p->next;
}
}
//刪除函式
template<class DataType>
DataType LinkList<DataType>::Delete(int i)
{
DulNode<DataType> * p=first;//p指向頭結點
int count=0;
DataType x;
while (p!=NULL && count<i) {//遍歷找到i-1的結點
p=p->next;
count++;
}
if (p==NULL||p->next==NULL) throw "i節點不存在或i的後續節點為空";
else {
// p為待刪除節點
x=p->data;
(p->prior)->next=p->next; //p的prior指向p的next a(i-1)->a(i+1)
(p->next)->prior=p->prior; //p的next指向p的prior a(i+1)->a(i-1)
}
return x;
}
//插入函式
template<class DataType>
void LinkList<DataType>::Insert(int i, DataType x)
{
DulNode<DataType> *s;
DulNode<DataType> * p=first;//p指向頭結點
int count=0;
while (p!=NULL&&count<i-1) {//遍歷找到i-1的結點
p=p->next;
count++;
}
if (p==NULL) throw "i節點不存在";
else{ s=new DulNode<DataType>;
s->data=x; //建立新結點
s->prior=p; //把s插入i-1和i中
s->next=p->next;
p->next->prior=s; //摘除i-1和i之間的鏈
p->next=s;
// s->next=p->next;p->next=s; //將結點s放在結點p之後
}
}
//查詢函式 通過值
template<class DataType>
int LinkList<DataType>::locate(DataType x)
{
DulNode<DataType> *p=NULL;
p=first;
int count=1;
while (p!=NULL) {
if (p->data==x) {
return count;
}
else{
p=p->next;
count++;
}
}
return count;
}
//查詢函式 通過下標
template<class DataType>
DataType LinkList<DataType>::Get(int i)
{
DulNode<DataType>* p=NULL;
p=first->next;
int count=1;
while (p!=NULL && count<i) {
p=p->next;
count++;
}
if (p==NULL) throw "輸入的x有誤";
else return p->data;
}
//求線性表長度演算法
template<class DataType>
int LinkList<DataType>::Length()
{
DulNode<DataType> *p=first->next;
int count=0;
while (p!=NULL) {
p=p->next;
count++;
}
return count;
}
template <class DataType>
LinkList<DataType>::LinkList(DataType a[], int n) //尾插法
{
DulNode<DataType> *s, *r;
first = new DulNode<DataType>;
r = first;
for (int i = 0; i < n; i++)
{
s = new DulNode<DataType>;
s->data = a[i];
r->next = s;
r= s;
}
r->next = NULL;
}
//無參建構函式
template<class DataType>
LinkList<DataType>::LinkList()
{
DulNode<DataType>*p;
first=p; //生成頭結點
first->next=NULL; //頭結點的next指標域置空
first->prior=NULL;
}
//解構函式
template<class DataType>
LinkList<DataType>::~LinkList()
{
while (first!=NULL) {
DulNode<DataType> *p;
std::cout<<"我已經被銷燬";
p=first; //暫存被釋放結點
first=first->next; //指向下一個結點
delete p; //刪除結點
}
}
int main(int argc, const char * argv[]) {
int n=0;
std::cout<<"你要錄入的學生數量為";
std::cin>>n;
int a[]={50,60,70,80};
LinkList<int> Student(a,n);
std::cout<<"-----------";
Student.PrintList();
std::cout<<"在第三個位置插入一個成績為20的學生";
Student.Insert(3, 20);
std::cout<<"-----------";
Student.PrintList();
std::cout<<"-----------";
std::cout<<"第三位學生的成績"<<Student.Get(3);
std::cout<<"現在總學生數量為"<<Student.Length();
return 0;
}
上圖的“我已經被銷燬”,說明呼叫了四次解構函式刪除了四個學生物件。
實驗總結:
這次雙鏈表實驗與單鏈表大部分相似,通過next指標來尋找資料然後進行操作,不同的是插入與刪除,要修改幾個指標的指向,還算可以,加強了對指標的認識。