单链表(带头结点)
结构体定义
提示:
- 应有数据域和指针域
typedef struct LinkNode {
int data;
struct LinkNode *next;
}LinkNode, LinkList;
单链表初始化
提示:
- 头结点创建是否成功?
- 头结点的指针域是否置空?
bool initList(LinkList* &L) {//L:指向头结点的指针
L = new LinkList();
if (!L) {//头结点创建是否成功?
return false;
}
L->next = NULL;//头结点的指针域是否置空?
return true;
}
要使得在函数内修改的变量在函数外有效,就必须使用"变量的指针"或"变量的引用".
要使得在函数内修改的指针在函数外有效,就必须使用"指针的指针"或"指针的引用"!
单链表的插入
在单链表的插入这里,我提供一种思考的思路.对所有链表,包括但不限于双向链表、循环链表,即先当"电灯泡",再"转正".具体来讲就是,新结点先单方面建立与链表的关系(即可以通过新结点找到其他结点,但不能通过其他结点找到新结点),然后在建立其他结点与新结点的关系(链入链表).
头插法和尾插法
提示:
- 传入的链表是否有效
bool listInsertHead(LinkList* L, int data) {
if (!L) {//传入的链表是否有效
return false;
}
LinkNode* node = new LinkNode;
node->data = data;
node->next = NULL;
node->next = L->next;
L->next = node;
return true;
}
bool listInsertTail(LinkList* L, int data) {
if (!L) {//传入的链表是否有效
return false;
}
LinkNode* node = new LinkNode;
node->data = data;
node->next = NULL;
LinkList* p = L;
while (p->next) {
p = p->next;
}
p->next = node;
return true;
}
任意位置插入
提示:
- 传入的链表是否有效
bool listInsert(LinkList* L, int e, int data) {
if (!L) {//传入的链表是否有效
return false;
}
LinkList* p = L;
LinkNode* node = new LinkNode();
node->data = data;
node->next = NULL;
for (int i = 0; i < e-1; i++) {//寻找插入位置
if (!(p = p->next)) {
cout << "插入失败!" << endl;
return false;
}
}
node->next = p->next;
p->next = node;
return true;
}
单链表的删除
提示:
- 删除位置是否合法
- 删除位置可能大于链表表长
- 是否释放了删除结点的内存?
void deleteList(LinkList* L, int e) {
if (e <= 0) {//删除位置是否合法
return;
}
LinkList *p = L;
LinkList *q;
for (int i = 0; i < e-1; i++) {
if (!(p = p->next)) {//删除位置可能大于链表表长
cout << "删除失败!" << endl;
return;
}
}
q = p->next;
p->next = p->next->next;
delete q;//是否释放了删除结点的内存?
}
打印单链表内元素
无提示,选择自己喜欢的风格
void printList(LinkList* L) {
LinkList* p = L;
while (p->next) {
p = p->next;
cout << p->data << "\t";
}
cout << endl;
}
全部代码及测试代码
#include <iostream>
using namespace std;
typedef struct LinkNode {
int data;
struct LinkNode *next;
}LinkNode, LinkList;
bool initList(LinkList* &L) {
L = new LinkList();
if (!L) {
return false;
}
L->next = NULL;
return true;
}
bool listInsertHead(LinkList* L, int data) {
if (!L) {
return false;
}
LinkNode* node = new LinkNode;
node->data = data;
node->next = NULL;
node->next = L->next;
L->next = node;
return true;
}
bool listInsertTail(LinkList* L, int data) {
if (!L) {
return false;
}
LinkNode* node = new LinkNode;
node->data = data;
node->next = NULL;
LinkList* p = L;
while (p->next) {
p = p->next;
}
p->next = node;
return true;
}
bool listInsert(LinkList* L, int e, int data) {
if (!L) {
return false;
}
LinkList* p = L;
LinkNode* node = new LinkNode();
node->data = data;
node->next = NULL;
for (int i = 0; i < e-1; i++) {//寻找插入位置
if (!(p = p->next)) {
cout << "插入失败!" << endl;
return false;
}
}
node->next = p->next;
p->next = node;
return true;
}
void deleteList(LinkList* L, int e) {
if (e <= 0) {
return;
}
LinkList *p = L;
LinkList *q;
for (int i = 0; i < e-1; i++) {
if (!(p = p->next)) {
cout << "删除失败!" << endl;
return;
}
}
q = p->next;
p->next = p->next->next;
delete q;
}
void printList(LinkList* L) {
LinkList* p = L;
while (p->next) {
p = p->next;
cout << p->data << "\t";
}
cout << endl;
}
int main(void) {
LinkList *L;
int n,e,data;
initList(L);
cout << "请输入插入元素的个数:";
cin >> n;
while (n--) {
cout << "请输入元素:";
cin >> data;
listInsertTail(L, data);
}
printList(L);
cout << "请输入插入元素的值:";
cin >> data;
cout << "请输入插入元素的位置:";
cin >> e;
listInsert(L, e, data);
printList(L);
cout << "请输入删除元素的位置:";
cin >> e;
deleteList(L, e);
printList(L);
system("pause");
return 0;
}