数据结构之链表篇

数据结构之链表篇

所有代码均出自郝斌老师数据结构教学视频
单链表的学习过程,我们需要明白几个重要定义:
头指针:
头结点:
首结点(第一个结点):
尾结点:

抽象链表的数据结构
typedef struct Node
{
	int data;
	struct Node* pNext;
}Node;//NODE 等价于struct NODE   PNODE等价于struct Node*
typedef struct Node* PNODE;
typedef struct Node NODE;

主要链表的操作及其函数的声明

PNODE create_list(void);          //创建链表
void traverse_list(PNODE pHead);  //遍历链表至输出
bool is_empty(PNODE pHead);       //判断链表是否为空链表
int length_list(PNODE pHead);     //链表长度求解函数
void sort_list(PNODE pHead);      //链表的数据排序
bool inset_list(PNODE pHead, int pos, int val);    //插入指定元素
bool delete_list(PNODE pHead, int pos, int *pVal); //删除指定元素

模块一:创建链表的操作:

操作条件:
输入参数:无输入参数
输出参数:头指针pHead

PNODE creat_list(void)
{
    int len,i,val;                             //len为结点个数,val用来临时存放用户输入的终点的值
    PNODE pHead = (PNODE)malloc(sizeof(NODE)); //分配一个不存放有效数据的头结点
    if (NULL==pHead)                           //为了判断动态分配内存是否成功
	{
		printf("分配失败,程序终止!\n");
		exit(-1);
	}
	PNODE pTail = pHead;                      //声明一个尾结点,尾结点和头结点为同一个结点
	pTail->pNext = NULL;                      //由于尾结点的指针域为NULL
    
    printf("请设置链表的结点的个数:len=");  //设置结点的长度
	scanf_s("%d",&len);
    for ( i = 0; i < len; i++)             //应用循环产生结点
	{
		printf("请输入第%d个结点:",i+1);  
		scanf_s("%d",&val);
		PNODE pNew = (PNODE)malloc(sizeof(NODE)); //每循环一次,就需要动态分配一个新的结点
		if (pNew == NULL)                         
		{
			printf("内存分配失败,程序终止!\n");
			exit(-1);
		}
		pNew->data = val;                    //分配结点成功,就需要对每个结点数据域和指针域进行相应的操作
		pTail->pNext = pNew;
		pNew->pNext = NULL;
		pTail = pNew;                 //最后分配的结点就是尾结点 
	}
	return pHead;
}

遍历链表输出操作:
由于创建的链表返回了头结点(头指针),既可以知道链表的全部信息。

void  traverse_list(PNODE pHead)
{
     PNODE p = pHead->pNext; //定义一个结点P,将头结点的指针域(指向首结点/第一个有效结点)赋值给P
     while(NULL!=P)
     {
		printf("%d\t",p->data);  //输出相应结点的有效数据
		p = p->pNext;           //将当前p的指针域赋值给p,那么p变成下一个结点。(不是连续的,不能应用p++)
	}
	printf("\n");
	return;
}
bool is_empty(PNODE pHead)
{
	if (pHead->pNext==NULL)    //如果头结点的指针域都是空,那么链表为空
		return true;
	else
		return false;
}

链表长度求解函数

int length_list(PNODE pHead)
{
    PNODE p=pHead->pNext;  //p就是首结点
    int len = 0;
    while(NULL!=P)
    {
       len++;
       p = p->pNext;
    }
    return len;
}

单链表的插入操作:

  1. 声明一个结点p指向链表的头结点
  2. 判断pos的位置,如果i<pos就遍历链表,让p的指针向后移动,指向下一个结点,i从0开始
  3. 若到链表p末尾还未空,则说明pos不合理
  4. 查找成功,声明一个新的空结点,动态分配内存
  5. 将插入数据元素赋值给新结点的数据域
  6. 执行单链表的插入标准语句,将p结点的指针域赋值给q结点的指针域,将q结点的地址赋值给p的指针域。
  7. 返回成功
bool inset_list(PNODE pHead, int pos, int val)
{
	int i = 0;
	PNODE p = pHead;
	while (NULL != p && i < pos - 1) {
		p = p->pNext;
		++i;
	}
	if (i>pos-1||NULL==p)
		return false;
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	pNew->data = val;
	PNODE q = p->pNext;
	p->pNext = pNew;
	pNew->pNext = q;
	return true;
}

链表指定删除数据元素操作
q的作用在于释放内存,避免内存的泄露

bool delete_list(PNODE pHead, int pos, int *pVal)
{
	int i = 0;
	PNODE p = pHead;
	while (NULL != p && i < pos - 1) {
		p = p->pNext;
		++i;
	}
	if (i > pos - 1 || NULL == p)
		return false;
	PNODE q = p->pNext;
	*pVal = q->data;
	p->pNext = p->pNext->pNext;
	free(q);
	q = NULL;
}

链表的排序

void sort_list(PNODE pHead)
{
	int i, j, t;
	int len = length_list(pHead);
	PNODE p, q;
	for (i = 0, p = pHead->pNext; i < len - 1; ++i, p = p->pNext)
	{
		for (j = i + 1, q = p->pNext; j < len; ++j, q = q->pNext)
		{
			if (p->data > q->data)
			{
				t = p->data;
				p->data = q->data;
				q->data = t;
			}
		}
	}
}
发布了1 篇原创文章 · 获赞 0 · 访问量 4
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览