单链表的简单面试题

<pre class="cpp" name="code">#define _CRT_SECURE_NO_WARNINGS 1
#include "SListNode.h"

void Test1()//PushBack   PopBack
{
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushBack(&pHead,0);
	PushBack(&pHead,1);
	PushBack(&pHead,2);
	PushBack(&pHead,3);
	PushBack(&pHead,4);

	PrintList(&pHead);

	PopBack(&pHead);
	PopBack(&pHead);

	PrintList(&pHead);
}

void Test2()//PushFront   PopFront   Find
{ 
	PSListNode ret = NULL;
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushFront(&pHead,0);
	PushFront(&pHead,1);
	PushFront(&pHead,2);
	PushFront(&pHead,3);
	PushFront(&pHead,4);

	PrintList(&pHead);

	PopFront(&pHead);
	PopFront(&pHead);
	//PopFront(&pHead);
	//PopFront(&pHead);
	//PopFront(&pHead);
	//PopFront(&pHead);

	PrintList(&pHead);

	ret = Find(&pHead,2);
	if (ret == NULL)
	{
		printf("no find\n");
	} 
	else
	{
		printf("%d \n",ret->data);
	}
}

void Test3()//Erase
{
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushBack(&pHead,0);
	PushBack(&pHead,1);
	PushBack(&pHead,2);
	PushBack(&pHead,3);
	PushBack(&pHead,4);
	PrintList(&pHead);

	//Erase(&pHead,Find(&pHead,2));
	Erase(&pHead,Find(&pHead,4));
	//Erase(&pHead,Find(&pHead,0));
	PrintList(&pHead);

	Insert(&pHead,Find(&pHead,2),8);
	Insert(&pHead,Find(&pHead,0),9);
	PrintList(&pHead);

	DestroyList(&pHead);
	PrintList(&pHead);
}

void Test4()//BubblingSort   EraseNotHead  ReverseLish  InsertFrontNode
{
	PSListNode ret = NULL;
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushBack(&pHead,9);
	PushBack(&pHead,1);
	PushBack(&pHead,8);
	PushBack(&pHead,3);
	PushBack(&pHead,6);
	PrintList(&pHead);

	BubblingSort(&pHead);
	PrintList(&pHead);

	EraseNotHead(Find(&pHead,8));
	PrintList(&pHead);

	ReverseLish(&pHead);
	PrintList(&pHead);

	InsertFrontNode(Find(&pHead,3),15);
	PrintList(&pHead);

	ret = FindMidNode(&pHead);
	printf("%d\n",ret->data);

	DelKNode(&pHead,3);
	PrintList(&pHead);

	DestroyList(&pHead);
	PrintList(&pHead);

}
int main()
{
	//Test1();
	//Test2();
	//Test3();
	Test4();
	system("pause");
	return 0;
}


 

 

 

 

 

#ifndef __SListNode_H__
#define __SListNode_H__
#pragma once  //能够保证头文件只被编译一次
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int DataType;

typedef struct SListNode 
{
	DataType data;
	struct SListNode *_NextNode;
}SListNode,*PSListNode;

// 初始化单链表(对于无头结点单链表,该函数没有意义)
void InitList(PSListNode* pHead);
// 销毁单链表
void DestroyList(PSListNode* pHead);
// 尾插
void PushBack(PSListNode* pHead, DataType data);
// 尾出
void PopBack(PSListNode* pHead);
// 头插
void PushFront(PSListNode* pHead, DataType data);
// 头出
void PopFront(PSListNode* pHead);
// 在链表中查找元素data
PSListNode Find(PSListNode* pHead, DataType data);
// 删除pos位置的结点(注意不能用那种替换形式)
void  Erase(PSListNode* pHead, PSListNode pos);
// 在链表的pos位置插入元素data
void  Insert(PSListNode* pHead, PSListNode pos, DataType data);
//打印链表存放的数据
void PrintList(PSListNode* pHead);
//写一个单链表的冒泡排序
void BubblingSort(PSListNode* pHead);
//删除一个无头链表的非尾结点
void EraseNotHead(PSListNode pos);
//反转(逆置)链表
void ReverseLish(PSListNode* pHead);
//(无头单链表)在当前节点前插入一个节点
void InsertFrontNode(PSListNode pos,DataType data);
//只遍历一遍,查找链表的中间结点
PSListNode FindMidNode(PSListNode* pHead);
//删除倒数第k个结点(k>1 && k<总长度)
void DelKNode(PSListNode* pHead,int k);

#endif//__SListNode_H__


 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include "SListNode.h"

//这里参的是二级指针,因为要对结构体指针的内容进行修改,所以必须传该指针的地址(即
//一个二级指针),一级指针相当于值传递,不会对实参有改变

void InitList(PSListNode* pHead)
{
	assert(pHead);
	pHead = NULL;
}

PSListNode ByeNode(DataType data)
{
	PSListNode pNewNode = (PSListNode)malloc(sizeof(struct SListNode));
	if (pNewNode != NULL)
	{
		pNewNode->data = data;
		pNewNode->_NextNode = NULL;//一定要记得把新开辟结点的下一个结点赋值为空
	} 
	else
	{
		printf("开辟内存失败\n");
	}

	return pNewNode;
}

void PrintList(PSListNode* pHead)
{
	PSListNode pNode = NULL;
	assert(pHead);
	if (*pHead == NULL)
	{
		return;
	} 
	else
	{
		pNode = *pHead;

		while (NULL != pNode)//最好写成while(NULL != pNode)
		{
			printf("%d ",pNode->data);
			pNode = pNode->_NextNode;
		}
		printf("\n");
	}
}

void PushBack(PSListNode* pHead, DataType data)
{
	PSListNode pNode = NULL;
	PSListNode pNewNode = NULL;
	assert(pHead);
	if (*pHead == NULL)
	{
		*pHead = ByeNode(data);
	} 
	else
	{
		pNode = *pHead;

		//找到尾结点
		while (NULL != pNode->_NextNode)
		{
			//保存尾结点
			pNode = pNode->_NextNode;
		}

		pNewNode = ByeNode(data);
		pNode->_NextNode = pNewNode;
		pNewNode->_NextNode = NULL;
	}
}

void PopBack(PSListNode* pHead)
{
	PSListNode pNode1 = NULL;   
	PSListNode pNode2 = NULL;
	assert(pHead);
    pNode1 = *pHead;

	if (*pHead == NULL)
	{
		printf("SListNode is emtpy\n");
		return;
	} 
	else if (pNode1->_NextNode == NULL) //当只剩下一个节点的情况下,要单独处理头指针
	{
		*pHead = NULL;
		free(pNode1);
		pNode1 = NULL;
	}
	else
	{
		while (pNode1->_NextNode != NULL)
		{
			pNode2 = pNode1;//用一个指针追踪当前指针,一遍记录当前位置
			pNode1 = pNode1->_NextNode;
		}

		pNode2->_NextNode = NULL;//保证链表最后一个节点的的_NextNode为空

		free(pNode1);//和malloc配套使用   释放最后一个节点
		pNode1 = NULL;//将释放掉的结点赋值为空,以防变成空指针
	}
}

void PushFront(PSListNode* pHead, DataType data)
{
	PSListNode pNode = NULL;
	assert(pHead);

	if (*pHead == NULL)
	{
		*pHead = ByeNode(data);
		(*pHead)->_NextNode = NULL;
	} 
	else
	{
		pNode = ByeNode(data);
		pNode->_NextNode = *pHead;
		*pHead = pNode;
	}
}

void PopFront(PSListNode* pHead)
{
	PSListNode pNode = NULL;
	assert(pHead);

	
	if (NULL == *pHead)
	{
		printf("SListNode is empty\n");
	} 
	else if ((*pHead)->_NextNode == NULL)
	{
		pNode = *pHead;
		*pHead = NULL;
		free(pNode);
		pNode = NULL;
	}
	else
	{
		pNode = *pHead;
		*pHead = (*pHead)->_NextNode;
		free(pNode);
		pNode = NULL;
	}
}

PSListNode Find(PSListNode* pHead, DataType data)
{
	PSListNode pNode = NULL;
	assert(pHead);

	pNode = *pHead;
	while (NULL != pNode)
	{
		if (pNode->data == data)
		{
			return pNode;
		} 
		else
		{
			pNode = pNode->_NextNode;
		}
	}

	return NULL;
}

void Erase(PSListNode* pHead, PSListNode pos)
{
	PSListNode pNode = NULL;
	PSListNode pNode2 = NULL;
	assert(pHead);
	assert(pos);

	pNode = *pHead;

	while (NULL != pNode)
	{
		if (pNode->_NextNode == pos )
		{
			pNode2 = pNode->_NextNode;
			pNode->_NextNode = pNode->_NextNode->_NextNode;
			free(pNode2);
			pNode2 = NULL;
		} 
		else if(pNode == pos)
		{
			*pHead = (*pHead)->_NextNode;
			free(pNode);
			pNode = NULL;
		}
		else
		{
			pNode = pNode->_NextNode;
		}
	}
}

void Insert(PSListNode* pHead, PSListNode pos, DataType data)
{
	PSListNode pNode = NULL;
	PSListNode pNewNode = NULL;
	assert(pHead);
	assert(pos);

	pNode = *pHead;

	while (NULL != pNode)
	{
		if (pNode->_NextNode == pos)
		{
			pNewNode = ByeNode(data);
			pNewNode->_NextNode = pNode->_NextNode;
			pNode->_NextNode = pNewNode;
			break;
		} 
		else if(pNode == pos)
		{
			pNewNode = ByeNode(data);
			pNewNode->_NextNode = *pHead;
			*pHead = pNewNode;
			break;
		}
		else
		{
			pNode = pNode->_NextNode;
		}
	}
}

void DestroyList(PSListNode* pHead)
{
	PSListNode pNode = NULL;
	PSListNode pNode2 = NULL;
	assert(pHead);

	pNode = *pHead;

	while (NULL != pNode)
	{
		pNode2 = pNode;
		pNode = pNode->_NextNode;
		free(pNode2);
		pNode2 = NULL;
	}
	*pHead = NULL;
}

void BubblingSort(PSListNode* pHead)
{
	PSListNode cur = NULL;
	PSListNode prev = NULL;
	DataType tmp = 0;
	assert(pHead);

	cur = *pHead;

	while (cur != prev)
	{
		while (cur->_NextNode != prev)
		{
			if (cur->data > cur->_NextNode->data)
			{
				tmp = cur->data;
				cur->data = cur->_NextNode->data;
				cur->_NextNode->data = tmp;
			}
			cur = cur->_NextNode;
		}
		prev = cur;
		cur = *pHead;
	}
}

void EraseNotHead(PSListNode pos)
{
	PSListNode Del = NULL;
	assert(pos->_NextNode != NULL);
	if (pos == NULL)
	{
		return;
	}

	pos->data = pos->_NextNode->data;

	Del = pos->_NextNode;
	pos->_NextNode = pos->_NextNode->_NextNode;
	free(Del);
	Del = NULL;
}


void ReverseLish(PSListNode* pHead)
{
	PSListNode cur = NULL;
	PSListNode NewpHead = NULL;
	assert(pHead);

	while((*pHead)->_NextNode != NULL)
	{
		NewpHead = *pHead;
		*pHead = (*pHead)->_NextNode;
		NewpHead->_NextNode = cur;
		cur = NewpHead;
	}

	(*pHead)->_NextNode = NewpHead;
}

void InsertFrontNode(PSListNode pos,DataType data)
{
	DataType tmp = 0;
	PSListNode pNewNode = NULL;
	if (pos == NULL)
	{
		return;
	}
	pNewNode = ByeNode(data);

	tmp = pNewNode->data;
	pNewNode->data = pos->data;
	pos->data = tmp;

	pNewNode->_NextNode = pos->_NextNode;
	pos->_NextNode = pNewNode;
}


PSListNode FindMidNode(PSListNode* pHead)
{
	PSListNode cur = NULL;
	PSListNode prev = NULL;
	PSListNode pNode = NULL;
	assert(pHead);

	pNode = *pHead;
	cur = pNode;
	prev = pNode;

	while (prev->_NextNode != NULL && prev->_NextNode->_NextNode != NULL)
	{
		cur = pNode->_NextNode;
		prev = pNode->_NextNode->_NextNode;
		pNode = pNode->_NextNode;
	}

	return cur;
}

void DelKNode(PSListNode* pHead,int k)
{
	PSListNode cur = NULL;
	PSListNode prev = NULL;
	PSListNode pNode = NULL;
	PSListNode Del = NULL;
	assert(pHead);
	assert(k > 1);
	pNode = *pHead;
	cur = pNode;
	prev = pNode;

	while (k--)//使prev指向需要删除结点的前一个结点
	{
		cur = cur->_NextNode;
	}
	while (cur->_NextNode != NULL)
	{
		cur = cur->_NextNode;
		prev = prev->_NextNode;
	}

	Del = prev->_NextNode;
	prev->_NextNode = prev->_NextNode->_NextNode;
	free(Del);
	Del = NULL;
}



 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值