数据结构之链表
链表的定义
线性表的链式存储,每个存储节点不仅包含了元素本身的信息,而且包含表示元素之间逻辑的信息。
链表的实现
linklist.h
//
// Created by YuanPeng on 2018/5/10.
//
#ifndef MYLIST_LINKLIST_H
#define MYLIST_LINKLIST_H
typedef char ElementType;
typedef struct ListNode{
ElementType data;
struct ListNode *next;
}*Node; //直接将结构体指针重命名
void createListF(Node &L, ElementType a[], int n); //创建链表头插法
void createListR(Node &L, ElementType a[], int n); //尾插法
void destoryList(Node &L); //销毁链表
bool isEmpty(Node L); //判断是否为空
int listLength(Node L); //返回链表长度
void display(Node L); //输出
bool getItem(Node L, int i, ElementType &e); //获得节点信息
int getLocate(Node L, ElementType e); //获得节点位置
bool insertItem(Node L, int i, ElementType e); //插入节点
bool deleteItem(Node L, int i, ElementType &e); //删除节点
bool add(Node L, ElementType e); //加入节点
void mergeList(Node L1, Node L2, Node &L3); //合并
#endif //MYLIST_LINKLIST_H
linklist.cpp
//
// Created by YuanPeng on 2018/5/10.
// 链表的基本操作
//
#include "linklist.h"
#include <iostream>
using namespace std;
void createListF(Node &L, ElementType a[], int n) {
//头插法创建链表
Node s;
L = (Node)malloc(sizeof(Node));
L->next = nullptr;
for (int i = 0; i < n; i++) {
s = (Node)malloc(sizeof(Node));
s->data = a[i];
s->next = L->next;
L->next = s;
}
}
void createListR(Node &L, ElementType a[], int n) {
// 尾插法创建链表
Node s, r;
L = (Node)malloc(sizeof(Node));
r = L;
for (int i = 0; i < n; i++) {
s = (Node)malloc(sizeof(Node));
s->data = a[i];
r->next = s;
r = s;
}
r->next = nullptr;
}
void destoryList(Node &L) {
// 销毁链表
Node preNode = L, pNode = L->next;
while (pNode != nullptr) {
free(preNode);
preNode = pNode;
pNode = preNode->next;
}
free(preNode);
}
bool isEmpty(Node L) {
// 判断是否为空
return (L->next == nullptr);
}
int listLength(Node L) {
// 返回链表长度
int n = 0;
Node pNode = L;
while (pNode->next != nullptr) {
n ++;
pNode = pNode->next;
}
return n;
}
void display(Node L) {
// 输出
Node pNode = L->next;
while (pNode != nullptr) {
cout<<pNode->data<<" ";
pNode = pNode->next;
}
cout<<endl;
}
bool getItem(Node L, int i, ElementType &e) {
// 获得节点信息
int j = 0;
Node pNode = L;
if (i <= 0) {
return false;
}
while (j < i && pNode != nullptr) {
j ++;
pNode = pNode->next;
}
if (pNode == nullptr) {
return false;
} else {
e = pNode->data;
return true;
}
}
int getLocate(Node L, ElementType e) {
// 获得节点位置
int i = 1;
Node pNode = L->next;
while (pNode != nullptr && pNode->data != e) {
pNode = pNode->next;
i ++;
}
if (pNode == nullptr) {
return false;
} else {
return i;
}
}
bool insertItem(Node L, int i, ElementType e) {
// 插入节点
int j = 0;
Node pNode = L, s;
if (i <= 0) {
return false;
}
while (j < i-1 && pNode != nullptr) {
j ++;
pNode = pNode->next;
}
if (pNode == nullptr) {
return false;
} else {
s = (Node)malloc(sizeof(Node));
s->data = e;
s->next = pNode->next;
pNode->next = s;
return true;
}
}
bool deleteItem(Node L, int i, ElementType &e) {
// 删除节点
int j = 0;
Node pNode = L, qNode;
if (i <= 0) {
return false;
}
while (j < i-1 && pNode != nullptr) {
j ++;
pNode = pNode->next;
}
if (pNode == nullptr) {
return false;
} else {
qNode = pNode->next;
if (qNode == nullptr) {
return false;
}
e = qNode->data;
pNode->next = qNode->next;
free(qNode);
return true;
}
}
/*
将两个单链表合并为一个新的单链表
L1 = {x1, x2, x3, ..., xn};
L2 = {y1, y2, y3, ..., ym};
m <= n L3 = {x1, y1, x2, y2, ..., xm, ym, xm+1, ... xn};
m > n L3 = {x1, y1, x2, y2, ..., xn, yn, yn+1, ... ym};
*/
bool add(Node L, ElementType e) {
//把节点添加到链表尾部 尾插法 只不过每次之插入一个
Node tempNode;
tempNode = (Node)malloc(sizeof(Node));
tempNode->data = e;
if (L->next == nullptr) { //当前节点为空
L->next = tempNode;
L->next->next = nullptr;
} else {
Node curNode = L->next;
while (curNode->next != nullptr) { //找到尾节点的下一个空节点
curNode = curNode->next;
}
if (curNode == nullptr) {
return false;
}
curNode->next = tempNode;
curNode->next->next = nullptr;
}
return true;
}
void mergeList(Node L1, Node L2, Node &L3) {
//二路归并
// Node pa = L1->next;
// Node pb = L2->next;
// Node s, r;
// L3 = (Node)malloc(sizeof(Node));
// r = L3;
//
// while (pa != nullptr && pb != nullptr) {
//
// }
int n = listLength(L1);
int m = listLength(L2);
Node curL1 = L1->next;
Node curL2 = L2->next;
L3 = (Node)malloc(sizeof(Node));
L3->next = nullptr;
Node preNode = L3->next;
if (m <= n) {
while (curL2 != nullptr) {
add(L3, curL1->data);
add(L3, curL2->data);
curL1 = curL1->next;
curL2 = curL2->next;
}
while (curL1 != nullptr) {
add(L3, curL1->data);
curL1 = curL1->next;
}
} else {
while (curL1 != nullptr) {
add(L3, curL1->data);
add(L3, curL2->data);
curL1 = curL1->next;
curL2 = curL2->next;
}
while (curL2 != nullptr) {
add(L3, curL2->data);
curL2 = curL2->next;
}
}
}