一、基本概念:
1、链表(LinkedList):使用指针进行构造的列表,又称为结点列表
2、数据域(data):存放数据
3、指针域(pointer):存放下一个节点的地址
4、节点(node):构成链表的基本单元
5、表头(head):数据域为空,指针域指向第一节点
6、表尾(tail):数据域不为空,指针域为空
二、基本构成:
1、由节点(node)构成,各节点结构如下:
(1)数据域:data
(2)指针域:ptrNext
typedef int SLLDATA;
typedef struct SLLNODE * SLLPTR;
typedef struct SLLNODE
{
SLLDATA data; //数据域
SLLPTR ptrNext; //指针域
}sllnode;
2、表头(head)
3、表尾(tail)
三、特点:
链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。
四、基本操作及代码实现:
1、创建一个空链表
//SLLCreate.cpp
#include "SingleLinkedList.h"
SLLNODE * SLLCreate()//创建一个空链表
{
SLLNODE * head = (SLLNODE *)calloc(1, sizeof(SLLNODE *) );
head->data = 0;
head->ptrNext = NULL;
return head;
}
2、插入操作
(1)不带表头,在表尾插入新节点
//SLLInsert.cpp
#include "SingleLinkedList.h"
SLLNODE * SLLInsert(SLLNODE * head, SLLDATA data)//插入,不带表头,在表尾插入,无序
{
if ( (0 == head->data) && (NULL == head->ptrNext) )//链表为空作为表头
{
head->data = data;
head->ptrNext = NULL;
}
else//链表不为空,表尾插入新的节点
{
SLLNODE * temp = head;
SLLNODE * node = (SLLNODE *)calloc(1, sizeof(SLLNODE *) );
node->data = data;
node->ptrNext = NULL;
while(temp->ptrNext != NULL)
{
temp = temp->ptrNext;
}
temp->ptrNext = node;
}
return head;
}
(2)带表头,在表尾插入新节点
//SLLInsert.cpp
#include "SingleLinkedList.h"
SLLNODE * SLLInsert(SLLNODE * head, SLLDATA data)//插入,带表头,在表尾插入,无序
{
SLLNODE * temp = head;
SLLNODE * node = (SLLNODE *)calloc(1, sizeof(SLLNODE *) );
node->data = data;
node->ptrNext = NULL;
while(temp->ptrNext != NULL)
{
temp = temp->ptrNext;
}
temp->ptrNext = node;
return head;
}
(3)带表头,按从小到大的顺序插入新节点
//SLLInsert.cpp
#include "SingleLinkedList.h"
SLLNODE * SLLInsert(SLLNODE * head, SLLDATA data)//插入,带表头,在表尾插入,有序
{
SLLNODE * temp = head;
SLLNODE * node = (SLLNODE *)calloc(1, sizeof(SLLNODE *) );
node->data = data;
node->ptrNext = NULL;
while( temp->ptrNext != NULL)
{
if (temp->ptrNext->data > data)
{
node->ptrNext = temp->ptrNext;//新节点与当前节点的后继节点相连
temp->ptrNext = node; //新节点接入当前节点
return head;
}
temp = temp->ptrNext;
}
temp->ptrNext = node;//当前节点最大直接接入尾节点
return head;
}
3、删除操作
//SLLCreate.cpp
#include "SingleLinkedList.h"
SLLNODE * SLLDelete(SLLNODE * head, SLLDATA deData)//删除数据与deData相等的节点
{
SLLNODE * temp = head;
cout<<"The data:"<<deData<<" will be delete!"<<endl;
while ( NULL != temp->ptrNext)
{
if ( deData == temp->ptrNext->data )
{
temp->ptrNext = temp->ptrNext->ptrNext;
return head;
}
temp = temp->ptrNext;
}
cout<<"Warning, there is no the data:"<<deData<<" to be delete!"<<endl;
return NULL;
}
4、查找操作
//SLLSearch.cpp
#include "SingleLinkedList.h"
SLLNODE * SLLSearch(SLLNODE * head, SLLDATA data)//查找
{
if ( (0 == head->data) && (NULL == head->ptrNext) )
{
cout<<"Error, list is empty!"<<endl;
return NULL;
}
else
{
SLLNODE * temp = head;
while (temp->data != data )
{
if (NULL == temp->ptrNext)//到表尾还未找到
{
cout<<"Warning, there is no the data:"<<data<<"!"<<endl;
return NULL;
}
temp = temp->ptrNext;
}
return temp;
}
}
5、求链表的长度
//
// SLLLength.cpp
//
#include "SingleLinkedList.h"
unsigned int SLLLength(SLLNODE * head) //链表结点数:不包含头结点
{
unsigned int length = 0;
SLLNODE * temp = head;
while (temp->ptrNext != NULL)
{
length++;
temp = temp->ptrNext;
}
return length;
}
6、排序
其实质是各节点的数据域采用冒泡法进行排序。
//
// SLLSort.cpp
//
#include "SingleLinkedList.h"
SLLNODE * SLLSort(SLLNODE * head) //排序
{
unsigned int n = SLLLength(head);
unsigned int i;
unsigned int j;
SLLNODE * ntemp1 = head;
SLLNODE * ntemp2;
SLLDATA dtemp;
for (i = 0; i < n-1; i++)
{
ntemp1 = ntemp1->ptrNext;
ntemp2 = ntemp1;
for (j = i+1; j < n; j++)
{
ntemp2 = ntemp2->ptrNext;
if (ntemp1->data > ntemp2->data)
{
dtemp = ntemp1->data;
ntemp1->data = ntemp2->data;
ntemp2->data = dtemp;
}
}
}
return head;
}
7、逆置
就是将各节点逆序重组链表。
//
// SLLReverse.cpp
//
#include "SingleLinkedList.h"
SLLNODE * SLLReverse(SLLNODE * head) //逆置
{
SLLNODE * p1;
SLLNODE * p2;
SLLNODE * p3;
if ( head->ptrNext == NULL || head->ptrNext->ptrNext == NULL)
{
return head;
}
p1 = head->ptrNext;
p2 = p1->ptrNext;
while (p2)
{
p3 = p2->ptrNext;
p2->ptrNext = p1;
p1 = p2;
p2 = p3;
}
head->ptrNext->ptrNext = NULL;
head->ptrNext = p1;
return head;
}
8、显示
//SLLShow.cpp
#include "SingleLinkedList.h"
void SLLShow(SLLNODE * head)//链表输出
{
SLLNODE * temp = head;
while (NULL != temp)
{
cout<<temp->data<<"->";
temp = temp->ptrNext;
}
cout<<"NULL"<<endl;
}
五、说明:
1、带表头的单向链表,便于删除和排序操作
2、主函数:
//main.cpp
#include "SingleLinkedList.h"
#define N 10
SLLDATA data[N] = {15, 13, 14, 77, 89, 90, 12, 23, 46, 56};
int main()
{
int i;
SLLNODE * head = SLLCreate();
for ( i = 0; i < N; i++ )
{
SLLInsert(head, data[i]);
}
cout<<"Origin data: ";
SLLShow(head);
if ( NULL != SLLDelete(head, 90) )
{
cout<<"Deleted data: ";
SLLShow(head);
}
SLLSort(head);
cout<<"Sorted data: ";
SLLShow(head);
SLLReverse(head);
cout<<"Reversed data: ";
SLLShow(head);
return 0;
}
3、头文件:
//SingleLinkedList.cpp
#ifndef __SINGLELINKEDLIST__H
#define __SINGLELINKEDLIST__H
/************************************************************************/
#include <iostream>
using namespace std;
/************************************************************************/
typedef int SLLDATA;
typedef struct SLLNODE * SLLPTR;
typedef struct SLLNODE
{
SLLDATA data; //数据域
SLLPTR ptrNext; //指针域
}sllnode;
/************************************************************************/
SLLNODE * SLLCreate();//创建一个空链表
SLLNODE * SLLInsert(SLLNODE * head, SLLDATA data); //插入
SLLNODE * SLLSearch(SLLNODE * head, SLLDATA data); //查找
SLLNODE * SLLDelete(SLLNODE * head, SLLDATA deData); //删除数据与deData相等的节点
SLLNODE * SLLSort(SLLNODE * head); //排序
SLLNODE * SLLReverse(SLLNODE * head); //逆置
unsigned int SLLLength(SLLNODE * head); //链表结点数:不包含头结点
void SLLShow(SLLNODE * head); //链表输出
/************************************************************************/
#endif
运行结果: