单链表是一种线性的数据结构,由一系列的节点组成,每一个节点包含数据域和指向下一个节点的指针。
**节点结构:**
数据域:存储节点值(如整数、字符等)。
指针域:指向下一个节点的地址,尾节点的指针为NULL;
##特性:
**1.动态结构:**无需预先分配内存,可动态分配扩展和收缩。
**2.单向连接:**每个节点仅指向后继节点,无法直接访问前驱。
**3.头指针:**通过头指针(head)访问链表,空链表时(head)为NULL;
插入/删除:
已知前驱节点:O(1);
遍历:O(n);
访问遍历:O(n);
直接代码(有头节点):
#include
#include
using namespace std;
typedef int Elemtype;
typedef struct Node{
Elemtype data;
Node *next;
}node,*LinkList;
//初始化 (有头节点)
void InitList(LinkList &L){
L = (LinkList)malloc(sizeof(node));
L->data = 0;
L->next = NULL;
}
//创建一个链表
void creatList(LinkList &L, int n){
LinkList p = L;
for(int i = 1; i <= n; i++){
LinkList newnode = (LinkList)malloc(sizeof(node));
newnode->data = i;
newnode->next = NULL;
p->next = newnode;
p = p->next;
L->data++;
}
}
//打印链表
void printList(LinkList L){
LinkList p = L->next;
cout<<"链表的长度为:"<<L->data<<",内容为:";
while(p != NULL){
cout<<p->data<<"->";
p = p->next;
}
cout<<"NULL"<<endl;
}
//头插法
void headnode(LinkList &L, Elemtype e){
LinkList newhead = (LinkList)malloc(sizeof(node));
newhead->data = e;
newhead->next = L->next;
L->next = newhead;
L->data++;
}
//尾插法
void endnode(LinkList &L,Elemtype e){
LinkList p = L;
LinkList newend = (LinkList)malloc(sizeof(node));
newend->data = e;
newend->next = NULL;
while(p->next != NULL){
p = p->next;
}
p->next = newend;
L->data++;
}
//删除节点(按下标)
void deletenode_01(LinkList &L,int i){
if(i < 1 || i > L->data){
cout<<"输入的i不合理"<<endl;
return;
}
LinkList p = L;
for(int j = 1; j <= i-1; j++){
p = p->next;
if(p->next == NULL){
cout<<i<<"位置不存在!!"<<endl;
}
}
LinkList q = p->next;//i
p->next = q->next;//指向i+1;
free(q);//删除q节点
L->data--;
}
//删除节点(按照节点值)
void deletenode_02(LinkList &L,Elemtype e){
if(L->data == 0){
cout<<"链表为空!!!"<<endl;
return;
}
LinkList pre = L;//头节点
LinkList fir = L->next;//第一个节点
while(fir != NULL){
if(fir->data == e){
pre->next = fir->next;
free(fir);
L->data--;
cout<<"成功删除"<<e<<"这个节点"<<endl;
return;
}
pre = fir;
fir = fir->next;
}
cout<<"找不到节点"<<e<<endl;
}
//查找节点(按照节点的值)返回下标
void findnode_01(LinkList &L,Elemtype e){
if(L->data == 0){
cout<<"此链表为空表!!!"<<endl;
return ;
}
LinkList q = L->next;
int index = 1;
while(q != NULL){
if(q->data == e){
cout<<"找到"<<e<<"的下标为"<<index<<endl;
return;
}
q = q->next;
index++;
}
cout<<"未找到"<<e<<"这个值"<<endl;
}
//查找节点(按照节点的下标) 返回值
void findnode_02(LinkList &L,int i){
if(i < 1 || i > L->data){
cout<<"输入范围错误:"<<endl;
return;
}
LinkList p = L->next;
int ansindex = 1;
while(p != NULL && ansindex < i){
p = p->next;
ansindex++;
}
if(p == NULL){
cout<<"链表长度小于声明长度"<<endl;
return ;
}
cout<<"找到下标为"<<i<<"的节点的值:"<<p->data<<endl;
return;
}
int main(){
LinkList L;
InitList(L);
cout<<"请输入要创建节点的个数:"<<endl;
int n;
cin >> n;
creatList(L,n);
printList(L);
cout<<"(采用头插法)请输入要添加的节点:"<<endl;
Elemtype a;
cin >> a;
headnode(L,a);
printList(L);
cout<<"(采用尾插法)请输入要添加的节点:"<<endl;
Elemtype b;
cin >> b;
endnode(L,b);
printList(L);
int index_1;
cout<<"请输入要删除节点的位置:"<<endl;
cin >>index_1;
deletenode_01(L,index_1);
printList(L);
Elemtype c;
cout<<"请输入要删除的节点数据:"<<endl;
cin >> c;
deletenode_02(L,c);
printList(L);
Elemtype e;
cout<<"请输入要查找的节点;"<<endl;
cin >>e;
findnode_01(L,e);
int index_2;
cout<<"请输入查找节点的下标:"<<endl;
cin >>index_2;
findnode_02(L,index_2);
return 0;
}
接下来是(无头节点):
/*
无头结点
*/
#include
using namespace std;
typedef int Elemtype;
typedef struct node{
Elemtype data;
node* next;
}LNode,*LinkList;
//typedef node LNode; 表示单链表的一个结点
//typedef node* LinkList; 表示一个单链表
//初始化
void InitList(LinkList &L){
L = NULL;
}
//创建新节点(工具链表)
LinkList createNode(Elemtype data){
LinkList newnode = (LinkList)malloc(sizeof(LNode));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
//创建链表(尾插法)
void createnode(LinkList &L, int n){
LinkList tail = NULL;//尾指针
for(int i = 1; i <= n; i++){
LinkList newnode = createNode(i);
if(L == NULL){
L = tail = newnode;//既是头指针,又是尾指针
}else{
tail->next = newnode;
tail = newnode;
}
}
}
//计算链表长度
int lengthList(LinkList L){
int count = 0;
while(L != NULL){
count++;
L = L->next;
}
return count;
}
//打印链表
void printList(LinkList L){
cout<<"链表的长度为:"<<lengthList(L)<<",内容为:"<<endl;
LinkList p = L;
while(p != NULL){
cout << p->data;
if(p->next != NULL){
cout<<"->";
}
p = p->next;
}
cout <<"->NULL"<<endl;
}
//头插法
void headnode(LinkList &L, Elemtype e){
LinkList newnode = createNode(e);
newnode->next = L;
L = newnode;
cout<<"插入成功!"<<endl;
}
//尾插法
void endnode(LinkList &L, Elemtype e){
LinkList newnode = createNode(e);
if(L == NULL){
L = newnode;
cout<<"插入成功!"<<endl;
return ;
}
LinkList p = L;
while(p->next != NULL){
p = p->next;
}
p->next = newnode;
cout<<"插入成功!"<<endl;
}
//按位置删除节点
void deletenode_01(LinkList &L,int pos){
if(pos < 1 || pos > lengthList(L) ){
cout<<"位置不合法!!!"<<endl;
return ;
}
//处理第一个节点
if(pos == 1){
LinkList temp = L;
L = L->next;
free(temp);
return ;
}
LinkList p = L;
for(int i = 1; i < pos-1;i++){
p = p->next;
}
LinkList temp = p->next;
p->next = temp->next;
free(temp);
cout<<"删除成功!"<<endl;
}
//按照节点的值进行删除
void deletenode_02(LinkList &L, Elemtype e){
if(L == NULL){
cout<<"空表,没有可删除的!!"<<endl;
return ;
}
// 阶段1:处理头节点为e的情况(可能连续多个)
if(L != NULL && L->data == e){
LinkList temp = L;
L = L->next; // 更新头指针
free(temp);// 释放原头节点
}
// 阶段2:处理后续节点(此时头节点一定不是e)
LinkList pre = L;//前驱指针
LinkList current;//当前指针
if(pre == NULL) return;//链表已空
current = pre->next;// 从第二个节点开始检查
while(current != NULL){
if(current->data == e){
// 删除current节点
pre->next = current->next;
free(current);
cout<<"成功删除"<<e<<endl;
current = pre->next;// 更新current
return;
}else{
// 指针后移
pre = current;
current = current->next;
}
}
cout<<"未找到此值"<<e<<endl;
}
//按值查找
void findnode_01(LinkList L, Elemtype e){
int pos = 1;
while(L != NULL){
if(L->data == e){
cout <<"查到值: "<<e<<"位置是:"<<pos<<endl;
return ;
}
pos ++;
L = L->next;
}
cout<<"未找到:"<<e<<endl;
}
//按位置查找
void findnode_02(LinkList L, int index){
if(index < 1 || index > lengthList(L)){
cout<<"输入的位置超出范围!!!"<<endl;
return ;
}
for(int i = 1; i < index; i++){
L = L->next;
}
cout <<"找到位置为:"<<index<<"的值为:"<<L->data<<endl;
}
//销毁链表
void destoryList(LinkList &L){
while(L != NULL){
LinkList temp = L;
L = L->next;
free(temp);
}
}
int main(){
LinkList L;
InitList(L);
cout<<"请输入要创建的节点数量:"<<endl;
int n;
cin >>n;
createnode(L,n);
printList(L);
cout<<"头插法插入值:"<<endl;
Elemtype e;
cin >>e;
headnode(L,e);
printList(L);
cout<<"尾插法插入值:"<<endl;
Elemtype a;
cin >>a;
endnode(L,a);
printList(L);
cout<<"输入要删除的位置:"<<endl;
int pos;
cin >>pos;
deletenode_01(L,pos);
printList(L);
cout << "输入要删除的值:"<<endl;
Elemtype c;
cin >> c;
deletenode_02(L, c);
printList(L);
cout<< "输入要查找的值:"<<endl;
Elemtype d;
cin >>d;
findnode_01(L,d);
printList(L);
cout<<"输入要查找的位置:"<<endl;
int index;
cin >>index;
findnode_02(L,index);
printList(L);
destoryList(L);
return 0;
}