1.定義結點類型:自定義一個結構體類型,包括兩個成員①數據域和②指針域
其中指針域是結點類型的指針
如typedef struct LNode
{
ElemType data;//數據域域,該結點存放的數據(類型爲基類型)
struct LNode *next;//LNode類型(即指向LNode類型的變量)的指針next;
}LNode;*LinkList;
理解代碼:①定義一個特定數據類型struct LNode,其包括兩個成員,分別命名爲數據域和指針域。
其中指針域爲LNode類型的指針。
②利用typedef 將數據類型換名
相當於typedef struct LNode LNode;//將struct LNode換名爲LNode,以後使用該類型定義變量時 就可以省略掉struct
和typedef struct LNode* LinkList;//將struct Lnode類型指針(如int *稱爲int型指針類型) 換名爲LinkList
⇒LinkList是指向LNode型的指針類型
2.訪問結點(結構體)成員(指針域next和數據域data)
①正常訪問:LNode ln1;ln1.data;
②指針訪問:LinkList p;(*p).data;
③→訪問:LinkList p;p→data;等同於(*p.data)
注意:p→next(*p.next);有兩個含義
①P所指向結點的指針域(此時p→next爲地址變量)
②P所指向結點的後繼結點指針(此時p→next爲指針變量)
分別方法-觀察前後變量。
如LinkList L;//定義一個頭指針
LinkList P;//定義一個位置指針(標記當前所指向的結點)
p=L→next;//將p初始化指向第一個結點(第一個元素結點),因爲等同於(*p).next,
而p爲指針變量,所以L→next只能爲指針變量(頭結點*p的後繼結點指針)
#include <iostream>
#include <stdlib.h>
#define Elemtype int
#define ok 1
#define OK 1
#define error 0
#define ERROR 0
#define overflow -2
#define OVERFLOW -2
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef int status;
typedef struct Node
{
//Node * 是Node類型指針 指向一個LNode變量
//Linklist和Node 兩個都是類型名
//typedef struct Node Node; struct LNode換名爲Node,以後使用該類型定義變量時 就可以省略掉struct
//typedef struct Node* LinkList;//將struct Lnode類型指針 換名爲LinkList
//LinkList是指向Node類型的指針,可用Linklist定義一個指向LNode類型的指針(比如定義一個頭指針,標示一個單鏈表)
Node * next;
Elemtype data;
} *LinkList,Node;
LinkList LinkListInit() {
Node *L;
L = (Node *)malloc(sizeof(Node)); //申請結點空間
if(L == NULL) { //判斷是否有足夠的內存空間
cout<<"申請內存空間失敗\n";
}
L->next = NULL; //將next設置爲NULL,初始長度爲0的單鏈表
return L;
}
status GetValid(LinkList L,int i,Elemtype &e) //返回第i個位置的元素值
{
//L爲帶頭結點的單鏈表的頭指針
//當第i個元素存在時其值賦給e並返回OK,否則返回ERROR
LinkList p=L->next;int j=1; //初始化,p指向第一個結點,j爲計數器 p=L->next 等同於 p=(*L).next;
// L指向變量(*p,即頭結點) 的next成員(頭結點的next域,即指向第一個元素結點的 LNode類型的指針變量)
while(p&&j<i) //j滿足最大i-1 p再指向下一個結點 即i
{
p=p->next; ++j; //順指針向後查找,直到p指向第i個元素或p爲空
}
if(!p||j>i) return ERROR; //第i個元素不存在(包括i<1的情況)
e=p->data;
return OK;
}
status Insert(LinkList &L,int i,Elemtype &e) //在第i個位置之前插入一個元素
{
//在帶頭結點的單鏈表中第i個位置之前插入元素e
LinkList p=L;int j=0; //p初始化爲頭指針,j爲計數器
while(p&&j<i-1) //尋找第i-1個結點
{
p=p->next; ++j; //順指針向後查找,直到p指向第i個元素或p爲空
}
if(!p||j>i-1) return ERROR; //i大於表長+1 或小於1
LinkList s=(LinkList)malloc(sizeof(Node));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
//單鏈表的建立1,頭插法建立單鏈表(每個新元素,都插入在第一個位置)
LinkList CreatH() {
Node *L;
L = (Node *)malloc(sizeof(Node)); //申請頭結點空間
L->next = NULL; //初始化一個空鏈表
Elemtype x; //x爲鏈表數據域中的數據
cout<<"please input the sequence list elements"<<endl;
//while(scanf("%d",&x) != EOF) { //ctrl+z 手動結束
while(cin>>x) { //c++的表示,結束方式一樣
Node *p;
p = (Node *)malloc(sizeof(Node)); //申請新的結點
p->data = x; //結點數據域賦值
p->next = L->next; //將結點插入到表頭L-->|2|-->|1|-->NULL
L->next = p;
}
cin.clear();
return L;
}
//單鏈表的建立2,尾插法建立單鏈表(每個新元素,都插入在第一個位置)
LinkList CreatT() {
Node *L;
L = (Node *)malloc(sizeof(Node)); //申請頭結點空間
L->next = NULL; //初始化一個空鏈表
Node *r;
r = L; //r始終指向終端結點,開始時指向頭結點
Elemtype x; //x爲鏈表數據域中的數據
cout<<"please input the sequence list elements"<<endl;
while(cin>>x){
Node *p;
p = (Node *)malloc(sizeof(Node)); //申請新的結點
p->data = x; //結點數據域賦值
r->next = p; //將結點插入到表頭L-->|1|-->|2|-->NULL
r = p;
}
r->next = NULL;
cin.clear();
return L;
}
//在帶頭結點的單鏈表L中,刪除第i個元素,並e返回其值
status Delete(LinkList &L,int i,Elemtype &e)
{
LinkList p=L;int j=0; //p初始化爲頭指針,j爲計數器
while(p->next&&j<i-1) //尋找第i個結點
{
p=p->next; ++j; //順指針向後查找,直到p指向第i個元素或p爲空
}
if(!(p->next)&&j<i-1)
return ERROR; //i大於表長+1 或小於1
LinkList q=p->next;
p->next=q->next;
e=q->data;
free(q);
return OK;
}
void CreateList(LinkList &L,int n)
{
//逆位序輸入n個元素的值,簡歷帶表頭結點的單鏈線性表L
LinkList s=(LinkList)malloc(sizeof(Node));
L->next=NULL; //先建立一個帶頭結點的單鏈表
for(int i=n;i>0;--i)
{
LinkList p=(LinkList)malloc(sizeof(Node));
}
LinkList p;
cin>>p->data; //輸入元素值
p->next=L->next;
L->next=p; //插入到表頭
}
void Print(LinkList L)
{
LinkList p; //指向指針
cout<<"the elements of the sequence list are :"<<endl;
for(p= L->next; p!= NULL; p = p->next)
{
cout<<p->data<<" ";
}
}
void menu(LinkList &L)
{
cout<<endl<<"1:Delete 2.Display 3.GetValid 4.Insert 5.Exit "<<endl;
int oper;
cin>>oper;
switch(oper)
{
case 1://刪除第i個元素並返回其值
{
cout<<"input the location of element which you decide to delete"<<endl;
int loc,tag; cin>>loc;
if(Delete(L,loc,tag)) //判斷的同時也執行了Delete函數進行了刪除操作
cout<<"delete success"<<endl;
else
cout<<"delete failed"<<endl;
menu(L);
break;
}
case 2: //打印
{
Print(L);
menu(L);
break;
}
case 3://返回 第i個位置的值
{
cout<<"input the location which you want to get valid"<<endl;
int loc; cin>>loc;
int tag;
if(!GetValid(L,loc,tag))
cout<<"getting failed";
else cout<<"the element's valid is "<<tag;
cout<<endl;
menu(L);
break;
}
case 4: //在第i個元素之前插入一個值
{
cout<<"input the location which you want to insert"<<endl;
int loc,tag;cin>>loc;
cout<<"please insert the element's valid";
cin>>tag;
if(Insert(L,loc,tag))
cout<<"insert successfully";
else
cout<<"insert failed";
menu(L);
break;
}
case 6: break;
}
}
int main()
{
LinkList L;
L = CreatT(); //ctrl+z 回車退出輸出
menu(L);
printf("\n");
}