嵌入式学习

笔记

 作业

1. 上课代码。循环单链表。

        Loop_List.h文件。

#ifndef __LOOP_LIST_H__
#define __LOOP_LIST_H__

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;


//创建单向循环链表
LinkList create_loop_list();
//创建结点
LNode* create_lnode(ElemType data);
//判空
int isEmpty(LinkList L);
//头插
void insert_head(LinkList L,ElemType data);
//打印循环单链表
void print_loop_list(LinkList L);
//尾插
void insert_tail(LinkList L,ElemType data);
//头删
void delete_head(LinkList L);
//按位置插入
void insert_pos(LinkList L,int pos,ElemType data);
//删除头结点
LinkList delete_node_head(LinkList L);
//输出删除头结点后的单向循环链表
void print_no_head(LinkList L);



#endif

         Loop_List.c文件。

#include "Loop_List.h"

//创建单向循环链表
LinkList create_loop_list()
{
	LinkList L=(LinkList)malloc(sizeof(LNode));	
	if(NULL==L)
	{
		printf("空间申请失败:\n");
		return NULL;
	}
	L->data=0;
	L->next=L;
	return L;
}

//创建结点
LNode* create_lnode(ElemType data)
{
	LNode *p=(LNode*)malloc(sizeof(LNode));
	if(NULL==p)
	{
		printf("空间申请失败\n");
		return NULL;
	}
	p->data=data;
	return p;
}

//判空
int isEmpty(LinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return -1;
	}
	return L->next==L?1:0;

}

//头插
void insert_head(LinkList L,ElemType data)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	LNode *new=create_lnode(data);
	new->next=L->next;
	L->next=new;
	L->data++;
	return;
}

//打印循环单链表
void print_loop_list(LinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty(L))
	{
		printf("链表为空\n");
		return;
	}
	LinkList p=L->next;
	while(p!=L)
	{
		printf("%3d",p->data);
		p=p->next;
	}
	putchar(10);
	return;
}

//尾插
void insert_tail(LinkList L,ElemType data)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	LinkList p=L;
	while(p->next!=L)
	{
		p=p->next;
	}
	LNode *new=create_lnode(data);
	new->next=p->next;
	p->next=new;
	L->data++;
	return;
}


//头删
void delete_head(LinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty(L))
	{
		printf("链表为空\n");
		return;
	}
	LinkList p=L->next;
	L->next=p->next;
	free(p);
	L->data--;
	return;
}

//按位置插入
void insert_pos(LinkList L,int pos,ElemType data)
{
	if(NULL==L)
	{
		printf("链表不存在\n");

	}
	if(pos < 1 || pos > L->data+1)
	{
		printf("插入位置不合理\n");
		return;
	}
	LinkList p=L;
	int count=0;
	while(count!=pos-1)
	{
		p=p->next;
		count++;
	}
	LNode *new=create_lnode(data);
	new->next=p->next;
	p->next=new;
	L->data++;
	return;
}

//删除头结点
LinkList delete_node_head(LinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return NULL;
	}
	if(isEmpty(L))
	{
		printf("链表为空\n");
		free(L);
		L=NULL;
		return L;
	}
	LinkList p=L;
	while(p->next!=L)
	{
		p=p->next;
	}
	p->next=L->next;
	LinkList q=L->next;
	free(L);
	return q;
}

//输出删除头结点后的单向循环链表
void print_no_head(LinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	LinkList p=L;
	/*
	//法1
	while(p->next!=L)
	{
		printf("%3d",p->data);
		p=p->next;
	}
	printf("%3d",p->data);
	*/
	//法2
	do{
		printf("%3d",p->data);
		p=p->next;
	}while(p!=L);
	putchar(10);
	return;
}

         main.c文件。

#include "Loop_List.h"


int main()
{
	LinkList L=create_loop_list();//新建循环单链表
	printf("头插法插入5个元素\n");
	insert_head(L,1);
	insert_head(L,2);
	insert_head(L,3);
	insert_head(L,4);
	insert_head(L,5);
	print_loop_list(L);
	printf("尾插法插入1个元素\n");
	insert_tail(L,6);
	print_loop_list(L);
	printf("头删,删除1个元素\n");
	delete_head(L);
	print_loop_list(L);
	printf("按位插入,在第二个位置插入元素\n");
	insert_pos(L,2,9);
	print_loop_list(L);
	printf("删除头结点,并打印删除头结点后的元素\n");
	LinkList T=delete_node_head(L);//删除头结点,然后新建结点去接新的表头
	L=NULL;//删除头结点后,原先的头结点要置为NULL
	print_no_head(T);//删除头结点后打印
	return 0;
}

2. 实现双向链表的头插、头删、尾插、尾删、按位置插入、按位置删除。

        double_list.h文件。

#ifndef __DOUBLE_LIST_H__
#define __DOUBLE_LIST_H__

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;
typedef struct DNode {
	ElemType data;
	struct DNode *prior,*next;
}DNode,*DLinkList;


//创建双向链表
DLinkList create_DLinkList();
//创建新结点
DNode* create_DNode(ElemType data);
//判空
int isEmpty_DLinkList(DLinkList L);
//头插
void insert_head(DLinkList L,ElemType data);
//双链表打印
void print_DLinkList(DLinkList L);
//头删
void delete_head(DLinkList L);
//尾插
void insert_tail(DLinkList L,ElemType data);
//尾删
void delete_tail(DLinkList L);
//按位置插入
void insert_locate(DLinkList L,int pos,ElemType data);
//按位置删除
void delete_locate(DLinkList L,int pos);


#endif

        double_list.c文件。

#include "double_list.h"

//创建双向链表
DLinkList create_DLinkList()
{
	DLinkList L=(DLinkList)malloc(sizeof(DNode));
	if(NULL==L)
	{
		printf("空间申请失败\n");
		return NULL;
	}
	L->data=0;
	L->prior=NULL;//头结点的prior永远指向NULL
	L->next=NULL;
	return L;
}

//创建新结点
DNode* create_DNode(ElemType data)
{
	DNode *p=(DNode*)malloc(sizeof(DNode));
	if(NULL==p)
	{
		printf("空间申请失败\n");
		return NULL;
	}
	p->data=data;
	p->prior=NULL;
	p->next=NULL;
	return p;
}

//判空
int isEmpty_DLinkList(DLinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return -1;
	}
	return L->next==NULL?1:0;
}

//头插
void insert_head(DLinkList L,ElemType data)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	DNode *s=create_DNode(data);
	s->next=L->next;
	if(L->next!=NULL)//为了防止一个结点都没有时,发生段错误
	{
		L->next->prior=s;
	}
	L->next=s;
	s->prior=L;
	L->data++;
	return;
}

//双链表打印
void print_DLinkList(DLinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty_DLinkList(L))
	{
		printf("链表为空\n");
		return;
	}
	DLinkList p=L->next;
	while(p!=NULL)
	{
		printf("%3d",p->data);
		p=p->next;
	}
	putchar(10);
}

//头删
void delete_head(DLinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty_DLinkList(L))
	{
		printf("链表为空\n");
		return;
	}
	DLinkList p=L->next,q=L->next;
	L->next=p->next;
	if(p->next!=NULL)
	{	
		p->next->prior=L;
	}
	free(q);
	L->data--;
	return;
}



//尾插
void insert_tail(DLinkList L,ElemType data)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	DLinkList p=L;
	while(p->next!=NULL)//循环找到尾结点
	{
		p=p->next;
	}
	DNode *s=create_DNode(data);
	s->next=p->next;
	s->prior=p;
	p->next=s;
	L->data++;
	return;
}



//尾删
void delete_tail(DLinkList L)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty_DLinkList(L))
	{
		printf("链表为空\n");
		return;
	}
	DLinkList p=L,q;
	while(p->next->next!=NULL)//循环找到尾结点的前驱
	{
		p=p->next;
	}
	q=p->next;
	p->next=NULL;
	free(q);
	L->data--;
	return;
}



//按位置插入
void insert_locate(DLinkList L,int pos,ElemType data)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(pos<1 || pos>L->data+1)
	{
		printf("插入位置不合理\n");
		return;
	}

	//方法1
	DLinkList p=L;
	int count=0;
	while(count!=pos-1)
	{
		p=p->next;
		count++;
	}
	DNode *s=create_DNode(data);
	s->next=p->next;
	if(p->next!=NULL)//为了防止再长度加1的位置插入时发生段错误
	{
		p->next->prior=s;
	}
	p->next=s;
	s->prior=p;
	L->data++;
/*
	//方法2,太麻烦
	DLinkList p=L->next;
	int count=1;
	while(count!=pos)
	{
		p=p->next;
		count++;
	}
	DNode *s=create_DNode(data);
	if(p!=NULL)
	{		
		p->prior->next=s;
		s->prior=p->prior;
		s->next=p;
		p->prior=s;
	}else if(NULL==p)
	{
		p=L;
		while(p->next!=NULL)
		{
			p=p->next;
		}
		s->next=p->next;
		s->prior=p;
		p->next=s;
	}
*/
	L->data++;
	return;
}


//按位置删除
void delete_locate(DLinkList L,int pos)
{
	if(NULL==L)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty_DLinkList(L))
	{
		printf("链表为空\n");
		return;
	}
	if(pos<1 || pos>L->data)
	{
		printf("删除位置不合理\n");
		return;
	}
	DLinkList p=L,q;
	int count=0;
	while(count!=pos-1)
	{
		p=p->next;
		count++;
	}
	q=p->next;
	p->next=q->next;
	if(q->next!=NULL)
	{
		q->next->prior=p;
	}
	free(q);
	L->data--;
	return;
}

        main.c文件。

#include "double_list.h"

int main()
{
	printf("双链表头插建立链表:\n");
	DLinkList L=create_DLinkList();//创建双链表
	insert_head(L,1);//头插
	insert_head(L,2);
	insert_head(L,3);
	insert_head(L,4);
	insert_head(L,5);
	print_DLinkList(L);
	printf("头删一个元素后的结果:\n");
	delete_head(L);//头删
	print_DLinkList(L);
	printf("尾插两个元素后的结果:\n");
	insert_tail(L,6);//尾插
	insert_tail(L,7);
	print_DLinkList(L);
	//printf("%d\n",L->data);
	printf("尾删一个元素后的结果:\n");
	delete_tail(L);//尾删
	print_DLinkList(L);
	//printf("%d\n",L->data);
	printf("在第2个位置插入9:\n");
	insert_locate(L,2,9);
	print_DLinkList(L);
	printf("删除第6个位置上的值:\n");
	delete_locate(L,6);
	print_DLinkList(L);
	return 0;
}

3. 总结链表和顺序表的区别。

        顺序表可以随机访问;且存储密度高;在除表尾之外,靠前面的位置插入和删除元素需要移动大量元素。链表不能随机访问;存储密度低;插入和删除元素的平均时间复杂度为O(n),但时间主要浪费在查找上,单纯插入和删除操作时间复杂度为O(1)。

4. 链表逆置。

方法1:

void reverse_link01(LinkList SL)
{
	if(NULL==SL)
	{
		printf("链表不存在\n");
		return;
	}
	if(isEmpty_link(SL))
	{
		printf("链表为空\n");
		return;
	}
	if(NULL==SL->next->next)//只有一个结点时,不用逆置
	{
		return;
	}
	//p为先保留的第二个结点,q暂时为野指针
	LinkList p=SL->next->next,q;
	SL->next->next=NULL;//让第一个结点指向NULL
	while(p!=NULL)
	{
		q=p->next;//在头插之前保留下一个要头插的结点的首地址
		p->next=SL->next;//头插
		SL->next=p;
		p=q;//让p指向下一个要头插的结点
	}
}

方法2:

void reverse_link02(LinkList SL)
{
    if(NULL==SL)
    {
        printf("链表不存在\n");
        return;
    }
    if(isEmpty_link(SL))
    {
        printf("链表为空\n");
        return;
    }
    if(NULL==SL->next->next)//链表只有一个元素时,不需要逆置
    {
        return;
    }
    LinkList p=SL->next,q=p->next,t=q->next;
    while(t!=NULL)
    {
        q->next=p;
        p=q;
        q=t;
        t=t->next;
    }
    q->next=p;
    SL->next->next=NULL;
    SL->next=q;
}

  • 16
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值