1. 单链表是按链式存储结构的线性表,链表的结点在内存中是随机存放的,既每个存储单元可以是连续的,也可以是不连续的.
2. 单链表的每一个结点要用到两个域,一个是数据域(用来表示结点的数据信息),一个是指针域(用来表示下一个结点的地址)
struct LinkNode{
int data; //数据域,可以是其他的类型
struct LinkNode *next; //后一个结点的地址
};
3.链表的优缺点: (1)、插入删除操作相对于顺序表不需要移动大量的元素,只需要修改前后结点的指针 (2)、采用动态内存分配,不会造成空间的浪费
缺点(1)、存储密度小 (2)、不能随机访问,查找时需要从头节点开始遍历,查找元素的时间复杂度大。
4. 相关的功能实现
// 点链表的初始化
bool initNode(LinkHead* &head) {//传递一个头节点的引用,可以是指针,引用的话,避免拷贝
head = new LinkHead; //分配内存
if (!head) return false; //内存分配失败
head->next = NULL;
return true;
}
//单链表的头插法(每一次插入元素都从头节点处插入)
bool insterNode_front(LinkHead*& head, int _data){
if(!head) return false; //判断传递进来的链表是否存在
LinkNode* p = new LinkNode; //生成一个新的节点
p->data = _data; //将传递进来的数据,放入结点的数据域
p->next = head->next;
head->next = p;
return true;
}
//尾插法 (每次插入元素都从尾部插入)
//尾插法
bool insterNode_back(LinkHead*& head, int _data) {
if (!head) return false; //判断链表是否为空
LinkNode* p,*last; //定义一个指向链表尾部的指针,和一个临时的指针
p = new LinkNode; //为插入的数据分配一个结点内存
p->data = _data;
last = head;
while (last->next) { //当一个结点的指针域为NULL,表示是尾结点
last = last->next;
}
p->next = last->next;
last->next = p;
return true;
}
//在链表的任意位置插入数据
补充: 先找到插入位置(i)的前一个位置(i-1)
// 任意位置插入
bool insterNode(LinkHead*& head, int i, int _data) {
LinkNode* p=NULL;
p = head;
int j = 0; //记录链表的位置
while (p && j < i - 1) {
p = p->next;
j++;
}
if (!p || j > i - 1) { //判断i的合法性 i可能<1,
return false;
}
else{
LinkNode* s = new LinkNode; //生成新的结点
s->data = _data;
s->next = p->next;
p->next = s;
return true;
}
}
//遍历整个链表 (从头结点开始)
//遍历整个链表
void print(LinkHead*& head) {
if (!head) return; //链表为空
LinkNode* p;
p = head->next;
while (p) {
cout << p->data << " ";
p = p->next;
}
}
//链表的删除操作
//删除元素
bool deleteDode(LinkHead*& head, int i) {
LinkNode* p = NULL;
LinkNode* s = NULL;
p = head;
if (!p || !p->next) return false; //判断链表是否为空,或者链表只有头结点
int index = 0; //记录结点位置
//遍历单链表
while ( p->next && index<i-1) {
p = p->next;
index++;
}
if (! p->next || index > i-1) { //判断i位置的合法性
return false;
}
else {
s = p->next;
p->next=p->next->next;
delete s; //释放结点内存
return true;
}
}
5 全部代码的综合 完整代码实现
#include<iostream>
#include<Windows.h>
using namespace std;
typedef struct _LinkNode {
int data; //数据域
_LinkNode* next; //指针域
}LinkHead,LinkNode;
//初始化头结点
bool initNode(LinkHead* &head) {
head = new LinkHead; //分配内存
if (!head) return false; //内存分配失败
head->next = NULL;
return true;
}
//头插法
bool insterNode_front(LinkHead*& head, int _data) {
if (!head) return false; //传入的链表为空
LinkNode* p = new LinkNode;
p->data = _data;
p->next = head->next;
head->next = p;
return true;
}
//遍历整个链表
void print(LinkHead*& head) {
if (!head) return; //链表为空
LinkNode* p;
p = head->next;
while (p) {
cout << p->data << " ";
p = p->next;
}
}
//尾插法
bool insterNode_back(LinkHead*& head, int _data) {
if (!head) return false;
LinkNode* p,*last;
p = new LinkNode;
p->data = _data;
last = head;
while (last->next) { //当一个结点的指针域为NULL,表示是尾结点
last = last->next;
}
p->next = last->next;
last->next = p;
return true;
}
// 任意位置插入
bool insterNode(LinkHead*& head, int i, int _data) {
LinkNode* p=NULL;
p = head;
int j = 0; //记录链表的位置
while (p && j < i - 1) {
p = p->next;
j++;
}
if (!p || j > i - 1) { //判断i的合法性 i可能<1,
return false;
}
else{
LinkNode* s = new LinkNode; //生成新的结点
s->data = _data;
s->next = p->next;
p->next = s;
return true;
}
}
//按值查找
bool find(LinkHead*& head, int e) {
LinkNode* node = NULL;
node = head->next; //从第一个结点开始遍历
while (node && node->data != e) {
node = node->next;
}
if (!node) {
return false;
}
else {
return true;
}
}
//查找第i个位置的值
bool find(LinkHead*& head, int e, int& _data) {
if (e <= 0) return false; //判断位置e的合法性
LinkNode* node = NULL;
node = head;
int index = 0;
while (node && index < e) {
node = node->next;
index++;
}
if (!node) {
return false;
}else {
_data = node->data;
return true;
}
}
//删除元素
bool deleteDode(LinkHead*& head, int i) {
LinkNode* p = NULL;
LinkNode* s = NULL;
p = head;
if (!p || !p->next) return false; //判断链表是否为空,或者链表只有头结点
int index = 0; //记录结点位置
//遍历单链表
while ( p->next && index<i-1) {
p = p->next;
index++;
}
if (! p->next || index > i-1) { //判断i位置的合法性
return false;
}
else {
s = p->next;
p->next=p->next->next;
delete s; //释放结点内存
return true;
}
}
//销毁单链表
void distroyNode(LinkHead*& head) {
LinkHead* p = head;
while (p) {
head = head->next;
cout << "\n释放:" << p->data << " 的内存" << endl;
delete p;
p = head;
}
}
int main(void) {
LinkHead* head; //定义一个头结点
initNode(head); //初始化
// 1.头插法
/*
for (int i = 0; i < 4; i++) {
insterNode_front(head, i);
}
*/
// 2.尾插法
for (int i = 0; i < 5; i++) {
insterNode_back(head, i);
}
// 3.在任一位置插入
if (insterNode(head, 4, 7)) {
cout << "插入成功!" << endl;
}
else {
cout << "插入失败!" << endl;
}
print(head);
cout << endl;
// 4.按值查找
/*
if (find(head,6)) {
cout << "查找成功" << endl;
}
else {
cout << "查找失败" << endl;
}*/
// 按位置查找
int data;
if (find(head, 1, data)) {
cout << data << endl;
}
else {
cout << "位置不存在" << endl;
}
// 删除第i个位置的元素
if (deleteDode(head, 0)) {
cout << "删除成功" << endl;
}
else {
cout << "删除失败" << endl;
}
print(head);
distroyNode(head);
system("pause");
print(head);
return 0;
}
效果显示