zoukankan      html  css  js  c++  java
  • 第一章---线性表之单链表的操作

    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    typedef int DataType;   //使int重命名为DataType 
    DataType flag = 0;   //flag是用来判断神魔时候输入数据结束 
    typedef struct Lnode{
    	DataType data;  //定义DataType为int ,存储结构为顺序存储 
    	struct Lnode *next;
    }Lnode,*LinkList; 
    
    /*
    	1.链表的创建方法  头插法,尾插法
    	2.链表分类  单链表,循环链表,双向链表
    	3.默认都建立带头节点的链表   头节点的数据域不定义数据   head要摸为NULL,要摸为第一个结点的地址 
    	4.单链表的创建方法
    	  头插法:数据输入和输出顺序相反
    	  尾插法:数据输入顺序和输出顺序相同 
    	5.基本操作     查找操作是链表的核心 决定着其他各项依赖于查找的方法的性能 插入和删除都依赖于查找操作 
    	单链表默认都创建带头结点的  因为再进行各种操作时 比如求长度,不带头结点的单链表我们要特殊考虑第一个节点是不是空表 
    	而带头结点的就不用考虑第一个节点
    		1.求带头结点的表长:int length_LinkList1(LinkList head) 
    		2 求不带头结点的表长:int length_LinkList(LinkList head) 
    		//下面方法都是操作默认带头结点的单链表 
    		3.按序号查找操作(返回第i个位置的指针地址):LinkList get_LinkList(LinkList head,int i) 
    		4.按值查找操作(返回第i个位置的指针地址): LinkList locate_LinkList(LinkList head,DataType x) 
    		5.插入结点操作(分为前插节点和后插节点)(在第i个结点之前插入节点x):int insertP_LinkList(LinkList head,int i,DataType x) 
    		6.插入结点操作(分为前插节点和后插节点)(在第i个结点之后插入节点x):int insertT_LinkList(LinkList head,int i,DataType x)  
    		7.删除结点操作(删除第i个结点):int del_LinkList(LinkList head,int i) 
    		8.多节点删除运算(从第i个结点开始连续删除k个结点):delK_LinkList(LinkList head,int i,int k) 
    */
    //头插法  不带头节点的单链表 
    LinkList create_LinkList(){
    	LinkList head;
    	head=NULL;  //创建一个头节点为空的链表
    	LinkList s;
    	DataType x;
    	cout<<"请输入x的值:";
    	cin>>x; 
    	while(x!=flag){
    		s=(LinkList)malloc(sizeof(Lnode));
    		s->data=x;
    		s->next=head;
    		head=s;
    		cin>>x; 
    	} 
    	return head;
    } 
    
    //不带头结点的显示链表方法 
    void out_LinkList(LinkList head){
    	LinkList p=head;
    	while(p->next!=NULL){
    		cout<<p->data<<" ";
    		p=p->next;
    	}
    	cout<<p->data;
    } 
    
    //头插法 带头节点的单链表
    LinkList create_LinkList1(){
    	LinkList p,head;
    	p->next=NULL; //设p是头节点
    	//p->data=0; //表示头节点的数据 
    	head=p;   //head是一个游标
    	LinkList s;
    	DataType x;
    	cout<<"请输入x的值:"; 
    	cin>>x;
    	while(x!=flag){
    		s=(LinkList)malloc(sizeof(Lnode));
    		s->data=x;
    		s->next=head;
    		head=s;
    		cin>>x;
    	}
    	return head;
    } 
    
    //带头结点的显示单链表的方法   不输出头结点的数据域 
    void out_LinkList1(LinkList head){
    	LinkList p=head;
    	while(p->next!=NULL){
    		cout<<p->data<<" ";
    		p=p->next; 
    	}
    } 
    
    //尾插法  不带头结点
    LinkList create_LinkListR(){
    	LinkList head,s,p;
    	head=p=NULL;
    	cout<<"请输入x的值:";
    	DataType x;
    	cin>>x;
    	while(x!=flag){
    		s=(LinkList)malloc(sizeof(Lnode));
    		s->data=x;
    		if(head==NULL){
    			//说明原来是空表
    			p=head=s; 		
    		}else{
    			p->next=s;
    			p=s;
    		}
    		cin>>x; 
    	}
    	p->next=NULL;
    	return head; //返回头结点的指针 
    } 
    
    //尾插法 带头结点
    LinkList create_LinkListR1(){
    	LinkList head,p,s;
    	//head->data=100;  可以给头结点数据域赋值验证 
    	head->next=NULL;  //带头节点
    	p=head;
    	DataType x;
    	cout<<"请输入x的值:";
    	cin>>x;
    	while(x!=flag){
    		s=(LinkList)malloc(sizeof(Lnode));
    		s->data=x;
    		p->next=s;
    		p=s;
    		cin>>x;
    	} 
    	p->next=NULL;
    	return head;
    } 
    
    //求带头结点的单链表的长度 (头节点不算入总长度) 
    int length_LinkList1(LinkList head){
    	//设置一个移动指针p和计数器count
    	LinkList p=head;
    	int count=0;
    	while(p->next!=NULL){
    		p=p->next;
    		count++;
    	}
    	return count;
    }
    
    //求不带头结点的单链表的长度  要考虑第一个节点 
    int length_LinkList(LinkList head){
    	//设置一个移动的指针和一个计数器 
    	LinkList p=head;
    	int count=0;
    	if(p==NULL){
    		cout<<"单链表为空!"<<endl;
    		return 0;
    	}else{
    		count=1;
    		while(p->next!=NULL){
    			p=p->next;
    			count++;
    		}
    		return count;
    	}
    } 
    
    //                   带头结点的   不需要判断是不是空表 
    
    
    //按序号查找操作  返回i位置的指针地址 
    LinkList get_LinkList(LinkList head,int i){
    	//判断i位置链表有没有 
    	LinkList p=head;
    	int count=0;
    	//这是一种思想,用循环包裹几种结果,在循环体外判断 
    	while(p->next!=NULL && i>count){
    		//循环结束只有两种情况,要摸链表到头了没找到,要摸找到了
    		p=p->next;
    		count++; 
    	}
    	if(i==count){ //找到了的情况 
    		return p;
    	}else{  //到头了的情况 
    		return NULL;
    	}
    }
    
    //按值查找
    LinkList locate_LinkList(LinkList head,DataType x){
    	LinkList p = head;
    	while(p->next!=NULL){
    		p=p->next;
    		if(p->data==x)
    			return p;
    	}
    	return NULL;
    }
    
    //前插节点  插入操作依赖于查找操作
    //单链表注意事项: 前置插入操作要找到待插入结点的前面一个结点 
    //如果链表是双向链表就没有这个烦恼了,直接找到位置插入即可 
    int insertP_LinkList(LinkList head,int i,DataType x){
    	LinkList p = head;  //保护头节点  重点  每个方法里面必须都写
    	LinkList q = get_LinkList(p,i-1);
    	LinkList s; //创建待插入节点 
    	s=(LinkList)malloc(sizeof(Lnode));
    	s->data=x;
    	if(q!=NULL){  //查找成功  找到了第i-1个结点 
    		s->next=q->next;
    		q->next=s;
    		return 0; //插入成功 
    	} else{
    		//cout<<"第i个结点不存在,不能插入第i个节点之前!"<<endl;
    		return -1;
    	}
    } 
    
    //后插节点  
    //单链表注意事项: 后置插入操作要找到待插入节点的后一个节点 
    //如果是双向链表就没有这个烦恼了 
    int insertT_LinkList(LinkList head,int i,DataType x){
    	LinkList p = head;  //保护现场    从汇编处学到的编程经验 
    	LinkList q = get_LinkList(p,i);  //查找后一个节点 
    	LinkList s; //创建待插入节点 
    	s=(LinkList)malloc(sizeof(Lnode)); 
    	s->data=x;
    	if(q==NULL){
    		cout<<"未找到第i个节点!"<<endl;
    		return -1;
    	}
    	if(q->next==NULL){//当前是最后一个节点 
    		q->next=s;
    		s->next=NULL;
    		return 0;
    	}
    	if(q->next!=NULL){
    		s->next=q->next;
    		q->next=s;
    		return 0;
    	}
    }
    
    //删除结点  删除第i个结点  要找到第i-1个结点 
    int del_LinkList(LinkList head,int i){
    	LinkList p = head;
    	LinkList q = get_LinkList(p,i-1);  //查找第i-1个结点 
    	if(q==NULL || q->next==NULL){  //不存在有两种情况 
    		cout<<"第i个结点不存在!删除失败!"<<endl; 
    		return -1;
    	} else{ //存在有两种情况 
    		if(q->next->next==NULL){//恰巧要删除的是最后一个结点 
    			free(q->next);
    			q->next=NULL;
    			return 0;
    		}else{  //要删除的结点在链表内部
    			 LinkList s;
    			 s=q->next;
    			 q->next=s->next;
    			 free(s);
    			 return 0;
    		}
    	}
     } 
     
    
    int main(int argc, char** argv) {
    	LinkList head = create_LinkListR1();
    	out_LinkList(head); 
    	cout<<endl; 
    	cout<<length_LinkList1(head)<<endl;
    	cout<<"插入操作:"<<endl;
    	int i = insertT_LinkList(head,3,100);
    	if(i==0){
    		out_LinkList(head);
    	}else{
    		cout<<"插入失败!"<<endl;
    	}
    	int j = del_LinkList(head,4);
    	if(j==0){
    		out_LinkList(head);
    	}else{
    		cout<<"error"<<endl;
    	}
    	free(head);
    	return 0;
    }
    

      

  • 相关阅读:
    剑指offer【面试题10 :矩形覆盖】
    剑指offer【面试题3 :二维数组中的查找】
    GStreamer Tutorials
    CMake Tutorial
    python
    python
    python-线程、进程、协程
    python-类的继承
    python-操作缓存
    python-线程池
  • 原文地址:https://www.cnblogs.com/nanfengnan/p/14378630.html
Copyright © 2011-2022 走看看