单链表的基本操作(包含有头节点和无头结点)

定义

单链表是一种线性的数据结构,由一系列的节点组成,每一个节点包含数据域和指向下一个节点的指针。
**节点结构:**
		数据域:存储节点值(如整数、字符等)。
		指针域:指向下一个节点的地址,尾节点的指针为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;
} 

你可能感兴趣的:(算法,链表)