完整代码如下,全部手打,如有错误,还望斧正
#include<bits/stdc++.h>
using namespace std;
#define ElemType int
/*
链表操作,带头节点的链表
*/
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList; //LiskList相当于LNode*,只是为了表达是一个是节点一个是链表的差别
/*
初始化操作,带头节点
*/
bool init(LinkList &L){
L = (LNode *)malloc(sizeof(LNode));
if(L==NULL) return false; //表示内存分配失败
L->next = NULL;
return true;
}
/*
头插入法
*/
void createListL(LinkList &L, ElemType a[], int n){ //L 要创建的链表, a 输入L中的数据, n 数组a的长度
LNode *s; //s用来表示新申请的节点
//以下两行相当于init(L)
L = (LNode *)malloc(sizeof(LNode));
L->next = NULL;
for(int i = 0; i < n; i++){
s = (LNode *)malloc(sizeof(LNode)); //新节点申请一个空间用来存储数据
s->data = a[i]; //把a[i]中的数据放入
s->next = L->next;
L->next = s; //把s节点插入到L中
}
}
/*
尾插入法
*/
void createListR(LinkList &L, ElemType a[], int n){ //L 要创建的链表, a 输入L中的数据, n 数组a的长度
LNode *s, *r; //s用来表示新申请的节点,r表示始终指向L终端的节点
//以下两行相当于init(L)
L = (LNode *)malloc(sizeof(LNode));
L->next = NULL;
r = L;
for(int i = 0; i < n; i++){
s = (LNode *)malloc(sizeof(LNode)); //新节点申请一个空间用来存储数据
s->data = a[i]; //把a[i]中的数据放入
r->next = s; //把s节点插入到L中
r = r->next; //r是指向尾指针的,所以要进行更新
}
r->next = NULL;
}
/*
删除节点,看给的条件是什么,
如果直接给的是一个节点,O(1)复杂度,只需要把其相邻的节点的值交换一下即可,
前提是删除的节点不是尾节点,如果是尾节点的话还是要O(n)的复杂度
如果给的是一个值,要删除链表中值为key的第一个节点,那么要O(1)的复杂度,要遍历一遍链表
*/
void deleteLNode1(LNode *node){
node->data = node->next->data;
node->next = node->next->next;
}
bool deleteLNode2(LinkList &L, int key){
LNode *p, *q;
q = L;
p = L->next;
while(p!=NULL){
if(p->data==key) break;
p = p->next;
q = q->next;
}
if(p==NULL) return false; //表示链表中不存在值为key的节点
else{
//deleteLNode1(p); //用到了一个删除的方法,但这个并不完美,因为这个节点不能为最后一个
q->next = p->next;
}
return true;
}
/*
改变节点
*/
bool changeElem(LinkList L, int i, ElemType key){
LNode *p = L->next;
while(p&&i) p = p->next, i--;
p->data = key;
return true;
}
/*
查询节点
*/
LNode *getElem(LinkList L, int i){ //从第0个节点开始计数
LNode *p = L->next;
while(p&&i) p = p->next, i--;
return p;
}
/*
打印链表
*/
void print(LinkList L){
L=L->next;
while(L){
cout<<L->data<<" ";
L=L->next;
}
cout<<endl;
}
/*
插入节点,在第i个位置插入key,即第i个位置的值为key
*/
void insertLNode(LinkList &L, int i, ElemType key){
LNode* p = getElem(L,i-1); //先找到第i-1个位置
LNode* s = (LNode *)malloc(sizeof(LNode));
s->data = key;
s->next = p->next;
p->next = s;
}
/*
主函数,包括对链表的一系列操作和解释
*/
int main(){
int a[] = {1,2,3,4,5};
LinkList L1, L2;
//创建链表,头插法,逆序
createListL(L1,a,5);
cout<<"链表L1数据如下:"<<endl;
print(L1);
cout<<endl;
//尾插法,正序
createListR(L2,a,5);
cout<<"链表L2数据如下:"<<endl;
print(L2);
cout<<endl;
LNode *c = getElem(L2,3); //查询正序第四个元素,我这里的代码是从零开始计算
cout<<"L2第4个元素的值为: "<<c->data<<endl;
cout<<endl;
insertLNode(L2, 3, 33); //在第四个位置插入33
cout<<"L2在第四个位置插入一个值:"<<endl;;
print(L2);
cout<<endl;
deleteLNode2(L2,5); //删除链表中第一个值为5的节点
cout<<"删除链表中第一个值为5的节点后:"<<endl;
print(L2);
cout<<endl;
changeElem(L2,4,99); //更改链表中第四个节点的值
cout<<"更改链表中第五个节点的值后:"<<endl;
print(L2);
cout<<endl;
return 0;
}
PS:acm过渡到数据结构的全部具体实现还是有那么点的生疏,