数据结构之单链表

/********************************************************
涉及到单链表的基本操作有如下:

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
请按任意键继续. . .

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值