嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)

嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY21

笔记:
1、双向链表

嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第1张图片

Struct DoubleLinkNode
{
Struct DoubleLinkNode *pPri;
Data_t data;
Struct DoubleLinkNode *pNext;
};

Struct DoubleLink
{
Struct DoubleLinkNode *pHead;
Int count;
}

头插:
嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第2张图片

pNode->pNext = pHead;
pHead->pPri = pNode;
pHead = pNode;

尾插:

嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第3张图片

pTmp = pHead;
While(pTmp->pNext != NULL)
{
pTmp = pTmp->pNext;
}
pTmp->pNext = pNode;
pNode->pPri = pTmp;

中间插入:
嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第4张图片

For(i = 0; i < iOffset-1; i++)
{
pTmp = pTmp->pNext;
}
pNode->pNext = pTmp->pNext;
pTmp->pNext->pPri = pNode;
pNode->pPri = pTmp;
pTmp->pNext = pNode;

头删:
嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第5张图片

pDel = pHead;
pHead = pDel->pNext;
pHead->pPri = NULL;
Free(pDel);

尾删:
嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第6张图片

Free(pDel);
pTmp->pNext = NULL;

中间删除:
嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第7张图片

pTmp = pHead;
For(i = 0; i < iOffset-1; i++)
{
pTmp = pTmp->pNext;
}
pTmp->pNext = pDel->pNext;
pDel->pNext->pPri = pTmp;

代码实现:
第一步:doublelink.h

#ifndef _DOUBLE_LINK_H_
#define _DOUBLE_LINK_H_

typedef int data_t;

//节点
typedef struct DoubleLinkNode
{
	struct DoubleLinkNode *pPri;
	data_t data;
	struct DoubleLinkNode *pNext;
}DoubleLinkNode;


//描述双向链表
typedef struct DoubleLink
{
	DoubleLinkNode *pHead;
	int count;
}DoubleLink;

enum DOUBLE_LINK_OP
{
	TAIL = -1,
	HEAD,
	DOUBLE_LINK_ERR,
	DOUBLE_LINK_OK
};

DoubleLink *createDoubleLink();
int insertItemDoubleLink(DoubleLink *pLink, int iOffset, data_t tData);
int deleteItemDoubleLink(DoubleLink *pLink, int iOffset, data_t *pData);
void showDoubleLink(DoubleLink *pLink);
void destroyDoubleLink(DoubleLink **ppLink);

#endif

第二步:doublelink.c

#include
#include "doubleLink.h"
#include 
#include 

DoubleLink *createDoubleLink()
{
	DoubleLink *pLink = (DoubleLink *)malloc(sizeof(DoubleLink));
	if(NULL == pLink)
	{
		return NULL;
	}
	memset(pLink, 0, sizeof(DoubleLink));
	return pLink;
}

int insertItemDoubleLink(DoubleLink *pLink, int iOffset, data_t tData)
{
	if(NULL == pLink || iOffset < -1)
	{
		return DOUBLE_LINK_ERR;
	}

	DoubleLinkNode *pNode = (DoubleLinkNode *)malloc(sizeof(DoubleLinkNode));
	if(NULL == pNode)
	{
		return DOUBLE_LINK_ERR;
	}
	memset(pNode, 0, sizeof(DoubleLinkNode));
	pNode->data = tData;

	//如果是空链表
	if(0 == pLink->count)
	{
		pLink->pHead = pNode;
		pLink->count++;
		return DOUBLE_LINK_OK;
	}

	DoubleLinkNode *pTmp = pLink->pHead;

	//如果iOffset的值很大,就直接插入到末尾
	if(iOffset >= pLink->count)
	{
		iOffset = TAIL;
	}
	int i;
	switch(iOffset)
	{
		case HEAD:
			pNode->pNext = pLink->pHead;
			pLink->pHead->pPri = pNode;
			pLink->pHead = pNode;
			break;
		case TAIL:
			while(pTmp->pNext != NULL)
			{
				pTmp = pTmp->pNext;
			}
			pTmp->pNext = pNode;
			pNode->pPri = pTmp;
			break;
		default:
			//中间插入
		    for(i = 0; i < iOffset-1; i++)
			{
				pTmp = pTmp->pNext;
			}
			pNode->pNext = pTmp->pNext;
			pTmp->pNext->pPri = pNode;
			pNode->pPri = pTmp;
			pTmp->pNext = pNode;
			break;
	}
	pLink->count++;
	return DOUBLE_LINK_OK;
}
int deleteItemDoubleLink(DoubleLink *pLink, int iOffset, data_t *pData)
{
	if(NULL == pLink || NULL == pLink->pHead || NULL == pData || iOffset < -1)
	{
		return DOUBLE_LINK_ERR;
	}

	DoubleLinkNode *pDel = pLink->pHead;
	DoubleLinkNode *pTmp = pLink->pHead;
	int i;

	//如果iOffset很大,就尾删
	if(iOffset >= pLink->count-1)
	{
		iOffset = TAIL;
	}

	switch(iOffset)
	{
		case HEAD:
			pLink->pHead = pDel->pNext;
			pLink->pHead->pPri = NULL;
			break;
		case TAIL:
			pDel = pTmp->pNext;
			//如果只剩下一个节点
			if(NULL == pDel)
			{
				pDel = pTmp;
				break;
			}
			while(pDel->pNext != NULL)
			{

				pTmp = pTmp->pNext;
				pDel = pTmp->pNext;
			}
			pTmp->pNext = NULL;
			break;
		default:
			for(i = 0; i < iOffset-1; i++)
			{
				pTmp = pTmp->pNext;
			}
			pDel = pTmp->pNext;
			pTmp->pNext = pDel->pNext;
			pDel->pNext->pPri = pTmp;
            
	}
	*pData = pDel->data;
	free(pDel);
	pDel = NULL;
	pLink->count--;
	return DOUBLE_LINK_OK;
}
void showDoubleLink(DoubleLink *pLink)
{
	if(NULL == pLink || NULL == pLink->pHead)
	{
		return;
	}
    DoubleLinkNode *pTmp = pLink->pHead;
	while(pTmp != NULL)
	{
		printf("%d  ", pTmp->data);
		pTmp = pTmp->pNext;
	}
	printf("\n");
}

void destroyDoubleLink(DoubleLink **ppLink)
{
	if(NULL == ppLink || NULL == *ppLink)
	{
		return;
	}

	DoubleLinkNode *pDel = (*ppLink)->pHead;
	while(pDel != NULL)
	{
		(*ppLink)->pHead = pDel->pNext;
		free(pDel);
		pDel = (*ppLink)->pHead;
	}
	free(*ppLink);
	*ppLink = NULL;
}

第三步:main.c

#include
#include "doubleLink.h"

int main()
{
	DoubleLink *pLink = createDoubleLink();
	insertItemDoubleLink(pLink, HEAD, 100);
	insertItemDoubleLink(pLink, HEAD, 200);
	insertItemDoubleLink(pLink, HEAD, 300);
	insertItemDoubleLink(pLink, TAIL, 888);
	insertItemDoubleLink(pLink, 2, 999);

	showDoubleLink(pLink);
	data_t data;
	deleteItemDoubleLink(pLink, HEAD, &data);
	showDoubleLink(pLink);
	deleteItemDoubleLink(pLink, TAIL, &data);
	showDoubleLink(pLink);
	deleteItemDoubleLink(pLink, 1, &data);
	showDoubleLink(pLink);

	destroyDoubleLink(&pLink);
	return 0;
}

二、栈和队列
1、栈和队列都是属于线性表
2、什么是线性表?—元素和元素之间的逻辑关系是一对一,那么就是线性表
3、线性表有两种存储结构:顺序存储 链式存储
4、顺序表----顺序存储的线性表
5、链表----链式存储的线性表
所以:栈有顺序栈也有链式栈、队列有顺序队列也有链式队列

本质上栈和队列都是线性表,只不过我们之前讲的顺序表和单链表对于哪里插入和哪里删除没有限制,头部、中间、尾部随便,无所谓,你需要哪种操作,都有,但是栈和队列就对顺序表和单链表的插入和删除操作进行了限制

栈只允许在头部插入和删除
队列只能在尾部插入,头部删除

顺序栈:
回忆顺序表:

Struct List
{
Data_t data[SIZE];
Int count;
};

嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第8张图片

Struct seqStack
{
Data_t data[SIZE];
Int iTop;  //栈顶元素的下标,初始值:-1,表示没有元素
};

顺序队列:
嵌入式学习DAY21 --- 数据结构(双向链表、栈、队列)_第9张图片

Struct seqQueue
{
Data_t data[SIZE];
Int iFront;   //队头的下标
Int iRear;   //队尾的下标
Int count; //当前队列的元素个数
};

顺序栈代码实现

一.stack.h

#ifndef _STACK_H_
#define _STACK_H_


#define SIZE 5

typedef int data_t;

typedef struct Stack
{
	data_t data[SIZE];
	int iTop;
}Stack;

enum STACK_OP
{
	STACK_ERR = -1,
	STACK_OK,
	STACK_FULL,
	STACK_EMPTY
};

Stack *createStack();
int pushStack(Stack *pStack, data_t tData);
int popStack(Stack *pStack, data_t *pData);
void destroyStack(Stack **ppStack);
int isEmpty(Stack *pStack);
int isFull(Stack *pStack);

#endif

二:stack.c

#include
#include "stack.h"
#include 
#include 


Stack *createStack()
{
	Stack *pStack = (Stack *)malloc(sizeof(Stack));
	if(NULL == pStack)
	{
		return NULL;
	}

	memset(pStack, 0, sizeof(Stack));
	pStack->iTop = -1;
	return pStack;
}

//入栈
int pushStack(Stack *pStack, data_t tData)
{
	if(NULL == pStack)
	{
		return STACK_ERR;
	}
	pStack->iTop++;
	pStack->data[pStack->iTop] = tData;
	return STACK_OK;
}

//出栈
int popStack(Stack *pStack, data_t *pData)
{
	if(NULL == pStack || NULL == pData)
	{
		return STACK_ERR;
	}
    *pData = pStack->data[pStack->iTop];
	pStack->iTop--;
	return STACK_OK;
}

void destroyStack(Stack **ppStack)
{
	if(NULL == *ppStack || NULL == ppStack)
	{
		return;
	}
	free(*ppStack);
	*ppStack = NULL;
}

int isEmpty(Stack *pStack)
{
	if(NULL == pStack)
	{
		return STACK_ERR;
	}
	if(-1 == pStack->iTop)
	{
		return STACK_EMPTY;
	}
	return STACK_OK;
}

int isFull(Stack *pStack)
{
	if(NULL == pStack)
	{
		return STACK_ERR;
	}
	if(SIZE == pStack->iTop+1)
	{
		return STACK_FULL;
	}
	return STACK_OK;
}

三:main.c

#include
#include "stack.h"


int main()
{
	Stack *pStack = createStack();

	data_t data;
	//如果栈不满,就入栈
	while(STACK_FULL != isFull(pStack))
	{
		scanf("%d", &data);
		pushStack(pStack, data);
	}



	//只要不为空,就出栈
	while(STACK_EMPTY != isEmpty(pStack))
	{
		popStack(pStack, &data);
		printf("出栈结果:%d ", data);
	}
	printf("\n");

	destroyStack(&pStack);
	return 0;
}

作业:
1、文件操作的作业重新完成
2、练习双向链表、顺序栈
3、自己实现链式栈

你可能感兴趣的:(队列,链表,数据结构,算法,c语言)