zoukankan      html  css  js  c++  java
  • 03 线性表的链式存储

    线性表的链式存储

    一、线性表的链式结构分类

    1.建立单链表

    引用的用处实际上就是使传入变量的本身可以被修改。

    ①传入引用型指针变量L , 数组a, 长度n
    ②定义一个指向结构体的指针变量s。
    ③初始化空链表L;
    ④循环:
    1.为指针s分配新的结点,并赋予数组的对应值,
    2.将s插入至头结点之后。
    s->next = L->next;
    L->next = s;

    尾插法
    ①传入引用型指针变量L , 数组a, 长度n
    ②定义两个指向结构体的指针变量s,r。
    ③初始化空链表L;
    ④令r = L,等价于尾结点。
    ④循环:
    1.为指针s分配新的结点,并赋予数组的对应值;
    2.将s插入在尾结点r之后;
    3.令r = s,重新成为尾结点。
    ⑤ r->next = NULL;

    /*头插法*/
    void CreateListF(LinkNode *&L, ElemType a[], int n){
        LinkNode *s;
        L = (LinkNode *)malloc(sizeof(LinkNode));
        L->next = NULL;
        for(int i = 0; i < n; i++){
            s = (LinkNode *)malloc(sizeof(LinkNode));
            s->data = a[i];
            s->next = L->next;
            L->next = s;
        }
    }
    
    /*尾插法*/
    void CreateListR(LinkNode *&L, ElemType a[], int n){
        LinkNode *s,*r;
        L = (LinkNode *)malloc(sizeof(LinkNode));
        L->next = NULL;
        r = L;
        for(int i = 0; i < n; i++){
            s = (LinkNode *)malloc(sizeof(LinkNode));
            s->data = a[i];
            r->next = s;
            r = s;
        }
        r->next = NULL;
    }
    

    2.初始化链表

    void InitList(ListNode *&L){
        L = (LinkNode *)malloc(sizeof(LinkNode));
        L->next = NULL;
    }
    

    3.销毁链表

    ①传入引用型指针变量L
    ②定义指向结构体的指针pre,并使其指向L;定义指向结构体的指针p,使其指向pre->next;
    ③循环:只要p!=NULL
    1.释放p的前一个结点pre;
    2.pre=p;
    p=pre->next;
    ④释放最后一个.pre

    void DestroyList(LinkNode *&L){
        LinkNode *pre = L, *P = pre->next;
        while(P != NULL){
            free(pre);
            pre = p;
            p = pre->next;
        }
        free(pre);
    }
    

    4.是否为空

    bool ListEmpty(LinkNode *L)
    {
    	return(L->next==NULL);//判断下一个指向的结构体指针是否为空
    }
    

    5.返回长度

    ①传入结构体指针L
    ②定义指向L的结构体指针p
    ③循环遍历p->next != NULL,i++
    ④返回 i

    int ListLength(LinkNode *L)
    {
    	LinkNode *p=L;
        int i=0;
    	while (p->next!=NULL)/
    	{	
            i++;
            p = p->next;
    	}
    	return i;//比实际结点数少1,因为有空头结点
    }
    

    6.输出单链表

    void DispList(LinkNode *L)
    {
    	LinkNode *p = L->next;
    	while (p!=NULL)
    	{	printf("%d ",p->data);
    		p = p->next;
    	}
    	printf("
    ");
    }
    

    7.获取第i个元素值

    bool GetElem(LinkNode *L, int i, ElemType &e){
        int j = 0;
        LinkNode *p =L;
        if(i<=0)
            return false;
        while(j < i && p != NULL){
            j++;
            p = p->next;
        }
        if(p == NULL)
            return false;
        else{
            e = p->data;
            return true;
        }
    }
    

    8.确认某个元素的位置

    int LocateElem(LinkNode *L,ElemType e)
    {
    	LinkNode *p=L->next;
    	int n = 1;
    	while (p!=NULL && p->data!=e)
    	{	p = p->next;
    		n++;
    	}
    	if (p==NULL)
    		return 0;
    	else
    		return n;
    }
    

    9.第i个位置插入元素

    ①判断 i
    ②查到第 i-1个 结点p
    ③插入至 p 后

    bool ListInsert(LinkNode *&L,int i,ElemType e)
    {
    	int j = 0;
    	LinkNode *p = L,*s;
    	if(i<=0) 
            return false;			//i错误返回假
    	while(j<i-1 && p!=NULL)		//查找第i-1个结点p
    	{	
             j++;
    		p=p->next;
    	}
    	if (p == NULL)					//未找到位序为i-1的结点
    		return false;
    	else							//找到位序为i-1的结点*p
    	{	
             s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
    		s->data = e;
    		s->next = p->next;			//将s结点插入到结点p之后
    		p->next = s;
    		return true;
    	}
    }
    

    10.删除第i个元素

    bool ListDelete(LinkNode *&L,int i,ElemType &e)
    {
    	int j = 0;
    	LinkNode *p = L,*q;
    	if (i <= 0) 
            return false;		//i错误返回假
    	while (j < i-1 && p!=NULL)	//查找第i-1个结点
    	{	
             j++;
    		p=p->next;
    	}
    	if (p == NULL)				//未找到位序为i-1的结点
    		return false;
    	else						//找到位序为i-1的结点p
    	{	
             q = p->next;				//q指向要删除的结点
    		if(q==NULL) 
    			return false;		//若不存在第i个结点,返回false
    		e = q->data;
    		p->next = q->next;		//从单链表中删除q结点
    		free(q);				//释放q结点
    		return true;
    	}
    }
    
    1. 全部代码

    #include <stdio.h>
    #include <malloc.h>
    #include <stdlib.h>
    #define MaxSize 50
    typedef int ElemType;
    typedef struct LNode  
    {
    	ElemType data;
    	struct LNode *next;		//指向后继结点
    } LinkNode;		
    void CreateListF(LinkNode *&L,ElemType a[],int n);
    void CreateListR(LinkNode *&L,ElemType a[],int n);
    void InitList(LinkNode *&L);
    void DestroyList(LinkNode *&L);
    bool ListEmpty(LinkNode *L);
    int ListLength(LinkNode *L);
    void DispList(LinkNode *L);
    bool GetElem(LinkNode *L, int i, ElemType &e);
    int LocateElem(LinkNode *L, ElemType e);
    bool ListInsert(LinkNode *&L,int i,ElemType e);
    bool ListDelete(LinkNode *&L,int i);
    
    void CreateListF(LinkNode *&L,ElemType a[],int n)
    //头插法建立单链表
    {
    	LinkNode *s;
    	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
    	L->next=NULL;
    	for (int i=0;i<n;i++)
    	{	
    		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
    		s->data=a[i];
    		s->next=L->next;			//将结点s插在原开始结点之前,头结点之后
    		L->next=s;
    	}
    }
    void CreateListR(LinkNode *&L,ElemType a[],int n)
    //尾插法建立单链表
    {
    	LinkNode *s,*r;
    	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
    	L->next=NULL;
    	r=L;					//r始终指向终端结点,开始时指向头结点
    	for (int i=0;i<n;i++)
    	{	
    		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
    		s->data=a[i];
    		r->next=s;			//将结点s插入结点r之后
    		r=s;
    	}
    	r->next=NULL;			//终端结点next域置为NULL
    }
    void InitList(LinkNode *&L)
    {
    	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
    	L->next=NULL;
    }
    void DestroyList(LinkNode *&L)
    {
    	LinkNode *pre=L,*p=pre->next;
    	while (p!=NULL)
    	{	free(pre);
    		pre=p;
    		p=pre->next;
    	}
    	free(pre);	//此时p为NULL,pre指向尾结点,释放它
    }
    bool ListEmpty(LinkNode *L)
    {
    	return(L->next==NULL);
    }
    int ListLength(LinkNode *L)
    {
    	LinkNode *p=L;int i=0;
    	while (p->next!=NULL)
    	{	i++;
    		p=p->next;
    	}
    	return(i);
    }
    void DispList(LinkNode *L)
    {
    	LinkNode *p=L->next;
    	while (p!=NULL)
    	{	printf("%d ",p->data);
    		p=p->next;
    	}
    	printf("
    ");
    }
    bool GetElem(LinkNode *L,int i,ElemType &e)
    {
    	int j=0;
    	LinkNode *p=L;
    	if (i<=0) return false;		//i错误返回假
    	while (j<i && p!=NULL)
    	{	j++;
    		p=p->next;
    	}
    	if (p==NULL)				//不存在第i个数据结点
    		return false;
    	else						//存在第i个数据结点
    	{	e=p->data;
    		return true;
    	}
    }
    int LocateElem(LinkNode *L,ElemType e)
    {
    	LinkNode *p=L->next;
    	int n=1;
    	while (p!=NULL && p->data!=e)
    	{	p=p->next;
    		n++;
    	}
    	if (p==NULL)
    		return(0);
    	else
    		return(n);
    }
    bool ListInsert(LinkNode *&L,int i,ElemType e)
    {
    	int j=0;
    	LinkNode *p=L,*s;
    	if (i<=0) return false;			//i错误返回假
    	while (j<i-1 && p!=NULL)		//查找第i-1个结点p
    	{	j++;
    		p=p->next;
    	}
    	if (p==NULL)					//未找到位序为i-1的结点
    		return false;
    	else							//找到位序为i-1的结点*p
    	{	s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
    		s->data=e;
    		s->next=p->next;			//将s结点插入到结点p之后
    		p->next=s;
    		return true;
    	}
    }
    bool ListDelete(LinkNode *&L,int i,ElemType &e)
    {
    	int j=0;
    	LinkNode *p=L,*q;
    	if (i<=0) return false;		//i错误返回假
    	while (j<i-1 && p!=NULL)	//查找第i-1个结点
    	{	j++;
    		p=p->next;
    	}
    	if (p==NULL)				//未找到位序为i-1的结点
    		return false;
    	else						//找到位序为i-1的结点p
    	{	q=p->next;				//q指向要删除的结点
    		if (q==NULL) 
    			return false;		//若不存在第i个结点,返回false
    		e=q->data;
    		p->next=q->next;		//从单链表中删除q结点
    		free(q);				//释放q结点
    		return true;
    	}
    }
    
    int main()
    {
        LinkNode *lk;
        ElemType a[6]= {5,8,7,2,4,9};
        ElemType e;
        int i,x,choice;
        printf("第一步.创建单链表......
    ");
        CreateListF(lk, a, 6);
        while(1){
        	printf("创建成功!请选择菜单执行相关操作
    ");
    	    printf("		1.销毁单链表
    ");
    	    printf("		2.判定单链表是否为空
    ");
    	    printf("		3.求单链表的长度
    ");
    	    printf("		4.输出单链表
    ");
    	    printf("		5.求单链表第i个位置上的元素
    ");
    	    printf("		6.查找单链表中元素e的位置
    ");
    	    printf("		7.在单链表第i个位置插入元素
    ");
    	    printf("		8.删除单链表第i个位置上的元素
    ");
    	    printf("		0.退出
    ");
    	    printf("		请输入你的选择:");
    	    scanf("%d",&choice);
    		switch(choice)
    		{
    			case 0: exit(0); 
    			case 1: DestroyList(lk);
    					printf("单链表销毁成功~~程序直接退出!!");
    					exit(0);
    			case 2: if(ListEmpty(lk))
    						printf("单链表为空!");
    					else
    						printf("单链表不为空!");
    					break;
    			case 3: printf("该单链表长度为%d
    ",ListLength(lk));
    					break;
    			case 4: printf("输出单链表:
    ");
    					DispList(lk);
    					break;
    			case 5: printf("请输入待查找元素的位置:");
    					scanf("%d",&i);
    					GetElem(lk, i, e);
    					printf("第%d个位置上的元素为%d",i,e);
    					break;
    			case 6: printf("请输入要查找的元素:");
    					scanf("%d",&x);
    					printf("%d元素在单链表的第%d个位置
    ",x,LocateElem(lk,x));
    					break;
    			case 7: printf("请输入要插入位置和值(空格隔开):");
    					scanf("%d%d",&i,&x);
    					ListInsert(lk,i,x);
    					break;
    			case 8: printf("请输入要删除的位置");
    					scanf("%d",&i);
    					ListDelete(lk, i, e);
    					break;
    		}
    		printf("按任意键继续……");
    		getchar();getchar();
        }
        return 0;
    }
    

    2.循环链表 CLinkNode

    #include <stdio.h>
    #include <malloc.h>
    #include <stdlib.h> 
    typedef int ElemType;
    typedef struct LNode
    {
    	ElemType data;
        struct LNode *next;
    } LinkNode;
    //头插法建立循环单链表
    void CreateListF(LinkNode *&L,ElemType a[],int n)
    {
    	LinkNode *s;
        int i;
    	L=(LinkNode *)malloc(sizeof(LinkNode));
    	L->next=NULL;
    	for (i=0;i<n;i++)
    	{	
    		s=(LinkNode *)malloc(sizeof(LinkNode));
    		s->data=a[i];
    		s->next=L->next;
    		L->next=s;
    	}
        /*令尾结点next指向头结点*/
    	s=L->next;	
    	while (s->next!=NULL)//查找尾结点,由s指向它
    		s=s->next;
    	s->next=L;//尾结点next域指向头结点
    
    }
    void CreateListR(LinkNode *&L,ElemType a[],int n)
    //尾插法建立循环单链表
    {
    	LinkNode *s,*r;
        int i;
    	L=(LinkNode *)malloc(sizeof(LinkNode));
    	L->next=NULL;
    	r=L;//r始终指向终端结点,开始时指向头结点
    	for (i=0;i<n;i++)
    	{	
    		s=(LinkNode *)malloc(sizeof(LinkNode));
    		s->data=a[i];
    		r->next=s;
    		r=s;
    	}
    	r->next=L;//尾结点next域指向头结点
    }
    void InitList(LinkNode *&L)
    {
    	L=(LinkNode *)malloc(sizeof(LinkNode));	//创建头结点
    	L->next=L;
    }
    void DestroyList(LinkNode *&L)
    {
    	LinkNode *p=L,*q=p->next;
    	while (q!=L)
    	{
    		free(p);
    		p=q;
    		q=p->next;
    	}
    	free(p);
    }
    bool ListEmpty(LinkNode *L)
    {
    	return(L->next==L);
    }
    int ListLength(LinkNode *L)
    {
    	LinkNode *p=L;
        int i=0;
    	while (p->next!=L)
    	{
    		i++;
    		p=p->next;
    	}
    	return(i);
    }
    void DispList(LinkNode *L)
    {
    	LinkNode *p=L->next;
    	while (p!=L)
    	{
    		printf("%d ",p->data);
    		p=p->next;
    	}
    	printf("
    ");
    }
    bool GetElem(LinkNode *L,int i,ElemType &e)
    {
    	int j=0;
    	LinkNode *p;
    	if (L->next!=L)//单链表不为空表时
    	{
    		if(i==1)
    		{
    			e=L->next->data;
    			return true;
    		}
    		else//i不为1时
    		{
    			p=L->next;
    			while (j<i-1 && p!=L)//j==i-1或者p==L时退出循环
    			{
    				j++;
    				p=p->next;
    			}
    			if (p==L)
    				return false;
    			else
    			{
    				e=p->data;
    				return true;
    			}
    		}
    	}
    	else//单链表为空表时
    		return false;
    }
    int LocateElem(LinkNode *L,ElemType e)
    {
    	LinkNode *p=L->next;
    	int n=1;
    	while (p!=L && p->data!=e)
    	{
    		p=p->next;
    		n++;
    	}
    	if (p==L)
    		return(0);
    	else
    		return(n);
    }
    bool ListInsert(LinkNode *&L,int i,ElemType e)
    {
    	int j=0;
    	LinkNode *p = L, *s;
    	if(p->next == L || i == 1)//原单链表为空表或i==1时
    	{
    		s = (LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
    		s->data = e;								
    		s->next = p->next;//将结点s插入到结点p之后
    		p->next = s;
    		return true;
    	}
    	else
    	{
    		p=L->next;
    		while (j<i-2 && p!=L)//第i-1个结点的序标为i-2 
    		{
    			j++;
    			p=p->next;
    		}
    		if (p==L)//未找到第i-1个结点
    			return false;
    		else//找到第i-1个结点p
    		{
    			s=(LinkNode *)malloc(sizeof(LinkNode));	//创建新结点s
    			s->data=e;								
    			s->next=p->next;//将结点s插入到结点p之后
    			p->next=s;
    			return true;
    		}
    	}
    }
    bool ListDelete(LinkNode *&L,int i,ElemType &e)
    {
    	int j=0;
    	LinkNode *p=L,*q;
    	if(p->next!=L)//原单链表不为空表时
    	{
    		if(i==1)//i==1时
    		{
    			q=L->next;//删除第1个结点
    			e=q->data;
    			L->next=q->next;
    			free(q);
    			return true;
    		}
    		else//i不为1时
    		{
    			p=L->next;
    			while (j<i-2 && p!=L)//第i-1个结点的序标为i-2 
    			{
    				j++;
    				p=p->next;
    			}
    			if(p==L)//未找到第i-1个结点
    				return false;
    			else//找到第i-1个结点p
    			{
    				q=p->next;//q指向要删除的结点
    				e=q->data;
    				p->next=q->next;//从单链表中删除q结点
    				free(q);
    				return true;
    			}
    		}
    	}
    	else return false;
    }
    
    int main()
    {
        LinkNode *lk;
        ElemType a[6]= {5,8,7,2,4,9};
        ElemType e;
        int i,x,choice;
        printf("第一步.创建循环单链表......
    ");
        CreateListF(lk, a, 6);
        while(1){
        	printf("创建成功!请选择菜单执行相关操作
    ");
    	    printf("		1.销毁循环单链表
    ");
    	    printf("		2.判定循环单链表是否为空
    ");
    	    printf("		3.求循环单链表的长度
    ");
    	    printf("		4.输出循环单链表
    ");
    	    printf("		5.求循环单链表第i个位置上的元素
    ");
    	    printf("		6.查找循环单链表中元素e的位置
    ");
    	    printf("		7.在循环单链表第i个位置插入元素
    ");
    	    printf("		8.删除循环单链表第i个位置上的元素
    ");
    	    printf("		0.退出
    ");
    	    printf("		请输入你的选择:");
    	    scanf("%d",&choice);
    		switch(choice)
    		{
    			case 0: exit(0); 
    			case 1: DestroyList(lk);
    					printf("单链表销毁成功~~程序直接退出!!");
    					exit(0);
    			case 2: if(ListEmpty(lk))
    						printf("单链表为空!");
    					else
    						printf("单链表不为空!");
    					break;
    			case 3: printf("该单链表长度为%d
    ",ListLength(lk));
    					break;
    			case 4: printf("输出单链表:
    ");
    					DispList(lk);
    					break;
    			case 5: printf("请输入待查找元素的位置:");
    					scanf("%d",&i);
    					GetElem(lk, i, e);
    					printf("第%d个位置上的元素为%d",i,e);
    					break;
    			case 6: printf("请输入要查找的元素:");
    					scanf("%d",&x);
    					printf("%d元素在单链表的第%d个位置
    ",x,LocateElem(lk,x));
    					break;
    			case 7: printf("请输入要插入位置和值(空格隔开):");
    					scanf("%d%d",&i,&x);
    					ListInsert(lk,i,x);
    					break;
    			case 8: printf("请输入要删除的位置");
    					scanf("%d",&i);
    					ListDelete(lk, i, e);
    					break;
    		}
    		printf("按任意键继续……");
    		getchar();getchar();
        }
        return 0;
    }
    
    #include <stdio.h>
    #include <malloc.h>
    #include <stdlib.h> 
    typedef int ElemType;
    typedef struct DNode//定义双链表结点类型
    {
    	ElemType data;
    	struct DNode *prior;//指向前驱结点
    	struct DNode *next;//指向后继结点
    } DLinkNode;
    
    //头插法建双链表
    void CreateListF(DLinkNode *&L,ElemType a[],int n)
    {
    	/* L、L->next*/ 
    	/* L、S、L->next*/ 
    	DLinkNode *s;
    	L = (DLinkNode *)malloc(sizeof(DLinkNode));
    	L->prior = L->next=NULL;//前驱后继初始化时均赋NULL 
    	for(int i = 0; i < n; i++)
    	{	
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));
    		s->data = a[i];
    		s->next = L->next;//first
    		if (L->next != NULL) 
    			L->next->prior = s;//second
    		L->next = s;//third
    		s->prior = L;//forth
    	}
    }
    //尾插法建双链表
    void CreateListR(DLinkNode *&L,ElemType a[],int n)
    {
    	/*r*/
    	/*r、s*/
    	DLinkNode *s, *r;
    	L = (DLinkNode *)malloc(sizeof(DLinkNode));
    	L->prior = L->next = NULL;//前驱后继初始化时均赋NULL 
    	r = L;//r始终指向终端结点,开始时指向头结点
    	for(int i = 0; i < n; i++)
    	{	 
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));
    		s->data = a[i];
    		r->next = s;//first 
    		s->prior = r;//second
    		r = s;//third 
    	}
    	r->next = NULL;//forth:尾结点next域置为NULL
    }
    void InitList(DLinkNode *&L)
    {
    	L = (DLinkNode *)malloc(sizeof(DLinkNode));
    	L->prior = L->next = NULL;
    }
    void DestroyList(DLinkNode *&L)
    {
    	DLinkNode *pre = L,*p = pre->next;
    	while (p!=NULL)
    	{
    		free(pre);
    		pre = p;
    		p = pre->next;
    	}
    	free(pre);
    }
    bool ListEmpty(DLinkNode *L)
    {
    	return(L->next==NULL);
    }
    int ListLength(DLinkNode *L)
    {
    	DLinkNode *p=L;
    	int i=0;
    	while (p->next!=NULL)
    	{
    		i++;
    		p=p->next;
    	}
    	return(i);
    }
    void DispList(DLinkNode *L)
    {
    	DLinkNode *p=L->next;
    	while (p!=NULL)
    	{
    		printf("%d ",p->data);
    		p=p->next;
    	}
    	printf("
    ");
    }
    bool GetElem(DLinkNode *L,int i,ElemType &e)
    {
    	int j=0;
    	DLinkNode *p=L;
    	if (i<=0) 
    		return false;	
    	while (j < i && p!=NULL)
    	{
    		j++;
    		p = p->next;
    	}
    	if (p==NULL)
    		return false;
    	else
    	{
    		e=p->data;
    		return true;
    	}
    }
    int LocateElem(DLinkNode *L,ElemType e)
    {
    	int n=1;
    	DLinkNode *p=L->next;
    	while (p!=NULL && p->data!=e)
    	{
    		n++;
    		p=p->next;
    	}
    	if (p==NULL)
    		return(0);
    	else
    		return(n);
    }
    bool ListInsert(DLinkNode *&L, int i, ElemType e)
    {
    	/* L、L->next*/ 
    	/* L、S、L->next*/ 
    	int j=0;
    	DLinkNode *p=L,*s;
    	if (i<=0) 
    		return false;//i错误返回假
    	while (j<i-1 && p!=NULL)
    	{
    		j++;
    		p=p->next;
    	}
    	if (p==NULL)//未找到第i-1个结点
    		return false;
    	else//找到第i-1个结点p
    	{
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));	//创建新结点s
    		s->data = e;	
    		s->next = p->next;//first 
    		if (p->next != NULL) 
    			p->next->prior = s;//second 
    		s->prior = p;//third 
    		p->next = s;//forth 
    		return true;
    	}
    }
    bool ListDelete(DLinkNode *&L,int i,ElemType &e)
    {
    	/*注意找的是前驱,第i-1个结点*/ 
    	/*p、q*/
    	/*i-1、i*/ 
    	int j = 0;
    	DLinkNode *p = L,*q;
    	if (i<=0) 
    		return false;
    	while (j < i-1 && p != NULL)
    	{
    		j++;
    		p = p->next;
    	}
    	if(p == NULL)//未找到第i-1个结点
    		return false;
    	else//找到第i-1个结点p
    	{
    		q = p->next;//q指向要删除的结点
    		if (q == NULL) 
    			return false;//不存在第i个结点
    		e = q->data;
    		p->next = q->next;//从单链表中删除*q结点
    		if(p->next!=NULL) 
    			p->next->prior = p;
    		free(q);
    		return true;
    	}
    }
    
    int main()
    {
        DLinkNode *lk;
        ElemType a[6]= {5,8,7,2,4,9};
        ElemType e;
        int i,x,choice;
        printf("第一步.创建双链表......
    ");
        CreateListF(lk, a, 6);
        while(1){
        	printf("创建成功!请选择菜单执行相关操作
    ");
    	    printf("		1.销毁双链表
    ");
    	    printf("		2.判定双链表是否为空
    ");
    	    printf("		3.求双链表的长度
    ");
    	    printf("		4.输出双链表
    ");
    	    printf("		5.求双链表第i个位置上的元素
    ");
    	    printf("		6.查找双链表中元素e的位置
    ");
    	    printf("		7.在双链表第i个位置插入元素
    ");
    	    printf("		8.删除双链表第i个位置上的元素
    ");
    	    printf("		0.退出
    ");
    	    printf("		请输入你的选择:");
    	    scanf("%d",&choice);
    		switch(choice)
    		{
    			case 0: exit(0); 
    			case 1: DestroyList(lk);
    					printf("双链表销毁成功~~程序直接退出!!");
    					exit(0);
    			case 2: if(ListEmpty(lk))
    						printf("双链表为空!");
    					else
    						printf("双链表不为空!");
    					break;
    			case 3: printf("该双链表长度为%d
    ",ListLength(lk));
    					break;
    			case 4: printf("输出双链表:
    ");
    					DispList(lk);
    					break;
    			case 5: printf("请输入待查找元素的位置:");
    					scanf("%d",&i);
    					GetElem(lk, i, e);
    					printf("第%d个位置上的元素为%d",i,e);
    					break;
    			case 6: printf("请输入要查找的元素:");
    					scanf("%d",&x);
    					printf("%d元素在双链表的第%d个位置
    ",x,LocateElem(lk,x));
    					break;
    			case 7: printf("请输入要插入位置和值(空格隔开):");
    					scanf("%d%d",&i,&x);
    					ListInsert(lk,i,x);
    					break;
    			case 8: printf("请输入要删除的位置");
    					scanf("%d",&i);
    					ListDelete(lk, i, e);
    					break;
    		}
    		printf("按任意键继续……");
    		getchar();getchar();
        }
        return 0;
    }
    
    //循环双链表基本运算算法
    #include <stdio.h>
    #include <malloc.h>
    #include <stdlib.h> 
    typedef int ElemType;
    typedef struct DNode//定义双链表结点类型
    {
    	ElemType data;
    	struct DNode *prior;//指向前驱结点
    	struct DNode *next;//指向后继结点
    } DLinkNode;
    
    //头插法建立循环双链表
    void CreateListF(DLinkNode *&L,ElemType a[],int n)
    {
    	DLinkNode *s;
    	int i;
    	L = (DLinkNode *)malloc(sizeof(DLinkNode));
    	L->next = NULL;
    	for(i = 0; i < n; i++)
    	{	
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));
    		s->data = a[i];
    		s->next = L->next;//first
    		if (L->next != NULL) 
    			L->next->prior = s;//second 
    		L->next = s;//third
    		s->prior = L;//forth
    	}
    	s = L->next;	
    	while (s->next!=NULL)//查找尾结点,使s指向它
    		s = s->next;
     	s->next = L;//first:使尾结点s的next域指向头结点
    	L->prior = s;//second:头结点的prior域指向尾结点
    
    }
    void CreateListR(DLinkNode *&L,ElemType a[],int n)
    //尾插法建立循环双链表
    {
    	DLinkNode *s,*r;
    	int i;
    	L = (DLinkNode *)malloc(sizeof(DLinkNode));
    	L->next=NULL;
    	r = L;//r始终指向尾结点,开始时指向头结点
    	for(i = 0; i < n; i++)
    	{	
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));
    		s->data = a[i];
    		r->next = s;//first 
    		s->prior = r;//second 
    		r = s;//third 
    	}
    	r->next = L;//first:尾结点next域指向头结点
    	L->prior = r;//second:头结点的prior域指向尾结点
    }
    void InitList(DLinkNode *&L)
    {
    	L = (DLinkNode *)malloc(sizeof(DLinkNode));
    	L->prior = L->next = L;
    }
    void DestroyList(DLinkNode *&L)
    {
    	DLinkNode *p = L, *q = p->next;
    	while(q!=L)
    	{
    		free(p);
    		p = q;
    		q = p->next;
    	}
    	free(p);
    }
    bool ListEmpty(DLinkNode *L)
    {
    	return(L->next==L);
    }
    int ListLength(DLinkNode *L)
    {
    	DLinkNode *p = L;
    	int i = 0;
    	while (p->next!=L)
    	{
    		i++;
    		p = p->next;
    	}
    	return(i);
    }
    void DispList(DLinkNode *L)
    {
    	DLinkNode *p = L->next;
    	while (p!=L)
    	{
    		printf("%d ",p->data);
    		p = p->next;
    	}
    	printf("
    ");
    }
    bool GetElem(DLinkNode *L, int i, ElemType &e)
    {
    	int j = 0;
    	DLinkNode *p;
    	if (L->next != L)//双链表不为空表时
    	{
    		if (i==1)
    		{
    			e = L->next->data;
    			return true;
    		}
    		else//i不为1时
    		{
    			p = L->next;
    			while (j<i-1 && p!=L)
    			{
    				j++;
    				p = p->next;
    			}
    			if(p == L)
    				return false;
    			else
    			{
    				e = p->data;
    				return true;
    			}
    		}
    	}
    	else//双链表为空表时
    		return 0;
    }
    int LocateElem(DLinkNode *L,ElemType e)
    {
    	int n = 1;
    	DLinkNode *p = L->next;
    	while (p!=NULL && p->data!=e)
    	{
    		n++;
    		p = p->next;
    	}
    	if (p == NULL)
    		return(0);
    	else
    		return(n);
    }
    bool ListInsert(DLinkNode *&L,int i,ElemType e)
    {
    	int j = 0;
    	DLinkNode *p = L,*s;
    	if (p->next==L)//原双链表为空表时
    	{	
    		/* p、s */ 
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));
    		s->data = e;
    		p->next = s;//first:即p->next指向p/L变为指向s 
    		s->next = p;//second:即s->next指回p 
    		p->prior = s;//third :即p->prior指向p/l变为指向s 
    		s->prior = p;//forth :s->prior指回p 
    		return true;
    	}
    	else if(i == 1)//原双链表不为空表但i=1时
    	{
    		/* p、p->next*/ 
    		/* p、s、p->next*/ 
    		s = (DLinkNode *)malloc(sizeof(DLinkNode));	//创建新结点s
    		s->data = e;
    		s->next = p->next;//first 
    		p->next = s;//second 
    		s->next->prior = s;//third 
    		s->prior = p;//forth 
    		return true;
    	}
    	else//插入i位置不为1时 
    	{	
    		p = L->next;
    		while (j < i-2 && p!=L)//第i-1个结点的序标为i-2 
    		{	
    			j++;
    			p = p->next;
    		}
    		if(p==L)//未找到第i-1个结点
    			return false;
    		else//找到第i-1个结点
    		{
    			s = (DLinkNode *)malloc(sizeof(DLinkNode));	
    			s->data = e;	
    			s->next = p->next;//first 
    			if (p->next!=NULL) 
    				p->next->prior=s;//second 
    			s->prior = p;//third 
    			p->next = s;//forth 
    			return true;
    		}
    	}
    }
    bool ListDelete(DLinkNode *&L,int i,ElemType &e)
    {
    	int j = 0;
    	DLinkNode *p=L,*q;
    	if (p->next!=L)//原双链表不为空表时
    	{	
    		if(i==1)//i==1时
    		{	
    			q=L->next;//删除第1个结点
    			e=q->data;
    			L->next=q->next;
    			q->next->prior=L;
    			free(q);
    			return true;
    		}
    		else//i不为1时
    		{	
    			p=L->next;
    			while(j<i-2 && p!=NULL)//第i-1个结点的序标为i-2 
    			{
    				j++;
    				p=p->next;
    			}
    			if(p==NULL)//未找到第i-1个结点
    				return false;
    			else//找到第i-1个结点p
    			{
    				q=p->next;//q指向要删除的结点
    				if (q==NULL) 
    					return 0;//不存在第i个结点
    				e=q->data;
    				p->next=q->next;//从单链表中删除q结点
    				if (p->next!=NULL) p->next->prior=p;
    				free(q);
    				return true;
    			}
    		}
    	}
    	else return false;//原双链表为空表时
    }
    
    int main()
    {
        DLinkNode *lk;
        ElemType a[6]= {5,8,7,2,4,9};
        ElemType e;
        int i,x,choice;
        printf("第一步.创建循环双链表......
    ");
        CreateListF(lk, a, 6);
        while(1){
        	printf("创建成功!请选择菜单执行相关操作
    ");
    	    printf("		1.销毁循环双链表
    ");
    	    printf("		2.判定循环双链表是否为空
    ");
    	    printf("		3.求循环双链表的长度
    ");
    	    printf("		4.输出循环双链表
    ");
    	    printf("		5.求循环双链表第i个位置上的元素
    ");
    	    printf("		6.查找循环双链表中元素e的位置
    ");
    	    printf("		7.在循环双链表第i个位置插入元素
    ");
    	    printf("		8.删除循环双链表第i个位置上的元素
    ");
    	    printf("		0.退出
    ");
    	    printf("		请输入你的选择:");
    	    scanf("%d",&choice);
    		switch(choice)
    		{
    			case 0: exit(0); 
    			case 1: DestroyList(lk);
    					printf("循环双链表销毁成功~~程序直接退出!!");
    					exit(0);
    			case 2: if(ListEmpty(lk))
    						printf("循环双链表为空!");
    					else
    						printf("循环双链表不为空!");
    					break;
    			case 3: printf("该循环双链表长度为%d
    ",ListLength(lk));
    					break;
    			case 4: printf("输出循环双链表:
    ");
    					DispList(lk);
    					break;
    			case 5: printf("请输入待查找元素的位置:");
    					scanf("%d",&i);
    					GetElem(lk, i, e);
    					printf("第%d个位置上的元素为%d",i,e);
    					break;
    			case 6: printf("请输入要查找的元素:");
    					scanf("%d",&x);
    					printf("%d元素在循环双链表的第%d个位置
    ",x,LocateElem(lk,x));
    					break;
    			case 7: printf("请输入要插入位置和值(空格隔开):");
    					scanf("%d%d",&i,&x);
    					ListInsert(lk,i,x);
    					break;
    			case 8: printf("请输入要删除的位置");
    					scanf("%d",&i);
    					ListDelete(lk, i, e);
    					break;
    		}
    		printf("按任意键继续……");
    		getchar();getchar();
        }
        return 0;
    }
    

    5.链栈 Listack

    //链栈基本运算算法
    #include <stdio.h>
    #include <stdlib.h> 
    #include <malloc.h>
    typedef int ElemType;
    typedef struct linknode
    {	
    	ElemType data;				//数据域
    	struct linknode *next;		//指针域
    } LinkStNode;					//链栈类型
    void InitStack(LinkStNode *&s)
    {
    	s=(LinkStNode *)malloc(sizeof(LinkStNode));
    	s->next=NULL;
    }
    void DestroyStack(LinkStNode *&s)
    {
    	LinkStNode *p=s->next;
    	while (p!=NULL)
    	{	
    		free(s);
    		s=p;
    		p=p->next;
    	}
    	free(s);	//s指向尾结点,释放其空间
    }
    bool StackEmpty(LinkStNode *s)
    {
    	return(s->next==NULL);
    }
    int StackLength(LinkStNode *s){
    	int i = 0;
    	while(s->next != NULL){
    		i++;
    		s = s -> next;
    	}
    	return i;
    }
    
    void Push(LinkStNode *&s,ElemType e)
    {
    	/*头插法*/ 
    	LinkStNode *p;
    	p=(LinkStNode *)malloc(sizeof(LinkStNode));
    	p->data=e;				//新建元素e对应的结点p
    	p->next=s->next;		//插入p结点作为开始结点
    	s->next=p;
    }
    bool Pop(LinkStNode *&s,ElemType &e)//出栈,由于头插法,因此很方便 
    {	
    	LinkStNode *p;
    	if (s->next==NULL)		//栈空的情况
    		return false;
    	p=s->next;				//p指向开始结点
    	e=p->data;
    	s->next=p->next;		//删除p结点
    	free(p);				//释放p结点
    	return true;
    }
    bool GetTop(LinkStNode *s,ElemType &e)
    {	
    	if (s->next==NULL)		//栈空的情况
    		return false;
    	e=s->next->data;
    	return true;
    }
    
    
    int main(){
    	LinkStNode *s;
    	ElemType e;
    	int i, x, choice;
    	printf("第一步.创建链栈......
    ");
    	InitStack(s);
        while(1){
        	printf("创建成功!请选择菜单执行相关操作
    ");
    	    printf("		1.销毁链栈
    ");
    	    printf("		2.判定链栈是否为空
    ");
    	    printf("		3.求链栈的长度
    ");
    	    printf("		4.输入入栈元素进栈
    ");
    	    printf("		5.使栈顶元素出栈
    ");
    	    printf("		6.获取栈顶元素
    ");
    	    printf("		0.退出
    ");
    	    printf("		请输入你的选择:");
    	    scanf("%d",&choice);
    		switch(choice)
    		{
    			case 0: exit(0); 
    			case 1: DestroyStack(s);
    					printf("链栈销毁成功~~程序直接退出!!");
    					exit(0);
    			case 2: if(StackEmpty(s))
    						printf("链栈为空!");
    					else
    						printf("链栈不为空!");
    					break;
    			case 3: printf("该链栈长度为%d
    ",StackLength(s));
    					break;
    			case 4: printf("请输入入栈元素:");
    					fflush(stdin);
    					scanf("%d",&e);//根据ElemType类型 
    					Push(s, e);
    					break;
    			case 5: printf("令栈顶元素出栈:");
    					Pop(s, e); 
    					printf("出栈元素为%d
    ",e);//根据ElemType类型 
    					break;
    			case 6: printf("获取栈顶元素:");
    					GetTop(s, e);
    					printf("栈顶元素为%d
    ",e);//根据ElemType类型 
    					break;
    		}
    		printf("按任意键继续……");
    		getchar();getchar();
        }
        return 0;
    }
    

    二、其它算法

    1. 如何判断链表是否有环,以及如何求该入环点

    2. 如何判断两条链表是否有交点,以及如何求该交点

    3. 两个循环链表合并为一张表

  • 相关阅读:
    cookie,请求报文,
    ser,ver
    关于 通知的 死循环,
    这读取的好蛋疼,为什么一写 一读就有问题了,不一致了,
    缓存小姐 挡拆,网络请求 不同步 惹的祸,
    viewdidload ,viewwillappear,
    提示输入 用户名 ,密码,--》转
    前端面试
    npm与cnpm
    vue与node和npm关系
  • 原文地址:https://www.cnblogs.com/Hokkaido-JL/p/11640111.html
Copyright © 2011-2022 走看看