/********************************************************
涉及到单链表的基本操作有如下:
int InitList(linkList *); //初始化一个单链表,具有头指针,头结点,头结点->next=NULL;
int CreateListHead(linkList *, int n); //头插法创建一个链表,链表长度为n;
int CreateListTail(linkList *, int n); //尾插法创建一个链表,链表长度为n;
int Getlength(linkList *); //获取单链表的长度;
int PrintList(linkList *); //打印整个链表;
int GetElem(linkList *,int i,ElemType *); //获取链表中第i个位置处节点的数据元素;
int InsertList(linkList *, int i, ElemType data); //在链表的指定位置(i节点)插入一个节点,i的范围为1~length(链表总长度);
int InsertListTail(linkList *, ElemType data); //给链表追加一个节点,在最末尾处增加;
int DeleteList(linkList *, int i, ElemType *data); //删除指定位置(i节点)处的节点,i的范围为1~length(链表总长度);
int ClearList(linkList *); //删除整个链表,使头结点->next=NULL;
缺点:查找的复杂度为O(n)
优点:插入和删除的时间复杂度为O(1),插入和删除操作很便利,不需要分配存储空间,只要有就可以分配,元素个数不受限制
使用环境:线性表中的元素个数变化较大或者根本不知道有多大的时候,最好利用单链表结构
*********************************************************/
#ifndef __LIST_H__
#define __LIST_H__
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; //类型定义 后面的所以Status都是表示int类型的
typedef int ElemType;
typedef struct Node//定义线性表的结构体
{
ElemType data ; //定义数据域
struct Node *next; //定义指针域,指向下一个结点的指针
}Node; //此Node是一个结构体变量
typedef struct Node *Sqlist; //定义线性表Sqlist
Status InitList(Sqlist *L)
{
(*L) = (Sqlist)malloc(sizeof(Node));
(*L)->next = NULL;
cout<<"链表初始化成功"<<endl;
return OK;
}
Status Getlength(Sqlist *L)
{
Sqlist p;
int length=0;
p = (*L)->next;//p指向第一个节点;
while (p)
{
length++;
p = p->next;
}
return length;
}
Status CreateListHead(Sqlist *L,int n) //头插法
{
Sqlist p;
int i = 0;
srand( 0);
for (i = 0; i < n; i++)
{
p = (Sqlist)malloc(sizeof(Node));
p->data = rand() % 100;
cout<<"Node["<<i+1<<"]="<<p->data<<endl;
p->next = (*L)->next;
(*L)->next = p;
}
printf("链表(头插法)创建成功\n");
return OK;
}
Status CreateListTail(Sqlist *L, int n)
{
Sqlist p, temp;
temp = (*L);
int i;
srand(0);
for (i = 0; i < n;i++)
{
p = (Sqlist)malloc(sizeof(Node));
p->data = rand() % 100;
cout<<"Node["<<i+1<<"]="<<p->data<<endl;
p->next = NULL;
temp->next = p;
temp = p;
}
cout<<"链表(尾插法)创建成功"<<endl;
return OK;
}
///****** 输出线性表中的全部元素***********/
Status OutputElem ( Sqlist *L)
{
int count=0;
Sqlist P;
P = (*L)->next;
cout<<"The list is : "<<endl;
while(P)
{
//注意这里不要搞混淆,要先输出,在指向下一个,
cout<< P->data<< " ";
P=P->next;
++count;
if(0 == count % 10)
{
cout<<endl;
}
}
cout<<"\n"<<"List总长度为: "<<count<<"\n";
return OK;
}
/****** 获取第i和元素 用指针e返回 *******/
Status GetElem ( Sqlist *L, int i , ElemType *e)
{
int j=1; //j为计数器
Sqlist P;//定义结点P
P = (*L) -> next;//将P指向L的第一个结点
while(P && j < i) //p还没有为空或者是j还没有等于i的时候循环
{
P = P->next;
++j;
}
if (!P || j > i)
{
cout<<"查询第 "<<i<<" 个元素失败,请重新查询"<<"\n";
return ERROR;
}
*e = P->data;
cout<<"查询第 "<<i<<" 个元素成功,值为: "<<*e<<endl;
return OK;
}
Status PrintList(Sqlist *L)
{
Sqlist p;
int i = 0;
p = (*L)->next;//p指向第一个节点;
cout<<"-----------打印整个链表-----------"<<endl;
if (p==NULL)
{
cout<<"这是一个空链表第"<<endl;
}
while (p)
{
i++;
cout<<"第"<<i<<"个节点的数据data:"<<p->data<<"节点插入成功"<<endl;
p = p->next;
}
return OK;
}
/******* 将i处的元素删除*****************/
Status DeleteElem( Sqlist *L, int i , ElemType *e)
{
int j=1;
Sqlist P,S;
P = *L;
cout<<"\n"<<"删除前List为:"<<"\n";
PrintList(L);
while(P->next && j < i) //寻找第i个结点
{
P = P->next;
++j;
}
if(!(P->next) || j > i)
{
cout<<"\n"<<"将第 "<<i<<" 位删除失败"<<"\n";
return ERROR;
}
S = P->next; //先把P这个结点赋值给S,
P->next = S->next; //在把这个S(P->next)的next指针赋值给p结点的next指针,这样就删除了S结点
*e = S->data; //再将S的结点的数据用e返回
cout<<"\n"<<"将第 "<<i<<" 位删除成功"<<"\n";
free (S); //将S结点释放
return OK;
}
/**** 将e插入到第i个元素处 **************/
Status InsertElem ( Sqlist *L,int i, ElemType e)
{
int j = 1;
Sqlist P,S; //定义两个结点
P = *L;
//OutputElem(L);
while( P && j < i) //寻找第i和结点
{
P = P->next;
++j;
}
if( !P || j > i)
{
cout<<"在第 "<<i<<" 位插入 "<< e <<"失败"<<"\n";
return ERROR;
}
S = (Sqlist)malloc(sizeof(Node)); //分配一个新的结点
S->data = e; //将元素e赋值给S的date
S->next = P->next; //将原来的P->next赋值为现在的S->next
P->next = S; //将前一个结点的P重新指向S结点
cout<<"在第 "<<i<<" 位插入 "<< e <<"成功"<<"\n";
return OK;
}
Status InsertListTail(Sqlist *L, ElemType data)
{
Sqlist temp;
Sqlist p=(*L);
while(p) {
temp = p;
p = p->next;
}
p = (Sqlist)malloc(sizeof(Node));
p->data = data;
p->next = NULL;
temp->next = p;
cout<<"节点插入成功"<<endl;
return OK;
}
Status ClearList(Sqlist *L) {
Sqlist p, temp;
p = (*L)->next;//p指向第一个节点
while (p) {
temp = p;
p = p->next;
free(temp);
}
(*L)->next = NULL;
cout<<"整个链表已经clear"<<endl;
return OK;
}
#endif // !__LIST__
Main函数
#include <stdlib.h>
#include "list.h"
#include <iostream>
using namespace std;
int main()
{
/*注意:指针指向的,我们可以使用&来引用*/
Sqlist L; //定义一个链表
int result=0;
int result1=0;
InitList(&L); //将此链表初始化化
CreateListHead(&L,10); //将这个链表创建5个元素
//CreateListTail(&L,50);
PrintList(&L);
DeleteElem(&L,5,&result);
cout<<"result = "<<result<<endl;
PrintList(&L);
InsertElem(&L,5,555);
PrintList(&L);
GetElem(&L,3,&result1);
cout<<"result1 = "<<result1;
InsertListTail(&L,666);
PrintList(&L);
OutputElem(&L);
cout<<endl<<"整个线性表的长度是:"<<Getlength(&L)<<endl;
ClearList(&L);
system("pause");
return 0;
}
编译结果:
链表初始化成功
Node[1]=38
Node[2]=19
Node[3]=38
Node[4]=37
Node[5]=55
Node[6]=97
Node[7]=65
Node[8]=85
Node[9]=50
Node[10]=12
链表(头插法)创建成功
-----------打印整个链表-----------
第1个节点的数据data:12节点插入成功
第2个节点的数据data:50节点插入成功
第3个节点的数据data:85节点插入成功
第4个节点的数据data:65节点插入成功
第5个节点的数据data:97节点插入成功
第6个节点的数据data:55节点插入成功
第7个节点的数据data:37节点插入成功
第8个节点的数据data:38节点插入成功
第9个节点的数据data:19节点插入成功
第10个节点的数据data:38节点插入成功
删除前List为:
-----------打印整个链表-----------
第1个节点的数据data:12节点插入成功
第2个节点的数据data:50节点插入成功
第3个节点的数据data:85节点插入成功
第4个节点的数据data:65节点插入成功
第5个节点的数据data:97节点插入成功
第6个节点的数据data:55节点插入成功
第7个节点的数据data:37节点插入成功
第8个节点的数据data:38节点插入成功
第9个节点的数据data:19节点插入成功
第10个节点的数据data:38节点插入成功
将第 5 位删除成功
result = 97
-----------打印整个链表-----------
第1个节点的数据data:12节点插入成功
第2个节点的数据data:50节点插入成功
第3个节点的数据data:85节点插入成功
第4个节点的数据data:65节点插入成功
第5个节点的数据data:55节点插入成功
第6个节点的数据data:37节点插入成功
第7个节点的数据data:38节点插入成功
第8个节点的数据data:19节点插入成功
第9个节点的数据data:38节点插入成功
在第 5 位插入 555成功
-----------打印整个链表-----------
第1个节点的数据data:12节点插入成功
第2个节点的数据data:50节点插入成功
第3个节点的数据data:85节点插入成功
第4个节点的数据data:65节点插入成功
第5个节点的数据data:555节点插入成功
第6个节点的数据data:55节点插入成功
第7个节点的数据data:37节点插入成功
第8个节点的数据data:38节点插入成功
第9个节点的数据data:19节点插入成功
第10个节点的数据data:38节点插入成功
查询第 3 个元素成功,值为: 85
result1 = 85节点插入成功
-----------打印整个链表-----------
第1个节点的数据data:12节点插入成功
第2个节点的数据data:50节点插入成功
第3个节点的数据data:85节点插入成功
第4个节点的数据data:65节点插入成功
第5个节点的数据data:555节点插入成功
第6个节点的数据data:55节点插入成功
第7个节点的数据data:37节点插入成功
第8个节点的数据data:38节点插入成功
第9个节点的数据data:19节点插入成功
第10个节点的数据data:38节点插入成功
第11个节点的数据data:666节点插入成功
The list is :
12 50 85 65 555 55 37 38 19 38
666
List总长度为: 11
整个线性表的长度是:11
整个链表已经clear
请按任意键继续. . .