删除链表中的重复节点、剩余节点逆序输出

#include <stdlib.h>
#include <algorithm>
#include <functional>
#include <iostream>
#include "oj.h"
using namespace std;

/*
功能:  输入一个不带头节点的单向链表(链表的节点数小于100),删除链表中内容重复的节点(重复的节点全部删除),剩余的节点逆序倒排。

输入:   pstrIn: 输入一个不带头节点的单向链表

输出:   pstrOut:删除内容重复的节点后,逆序排列的链表(不带头节点,链表第一个节点的内存已经申请)。

返回:

示例:
输入链表的内容依次为 6,7,8,8,9,10,6
则输出链表的内容依次应该是 10,9,7

*/

int iChanProcess(strNode * pstrIn,strNode * pstrOut)
{
	if (NULL == pstrIn || NULL == pstrOut)
	{
		return -1;
	}
	strNode *pCur = pstrIn;
	int len = 0;
	while (NULL != pCur)
	{
		len++;
		pCur = pCur->pstrNext;
	}

	int *iArray = new int [len];
	pCur = pstrIn;
	int iCur =0;
	while (NULL != pCur)
	{
		iArray[iCur] = pCur->data;
		iCur++;
		pCur = pCur->pstrNext;
	}
	sort(iArray,iArray + len, greater<int>());
	pCur = pstrOut;
	iCur = 0;
	int flag = 0; //标记输出的第一个节点是否被使用

	int *iArrayTemp = new int [len];

	memset(iArrayTemp, 0 , sizeof(int) * len);

	int iCurTemp =0;
	int tempLen = 0;

	if (iArray[iCur] ==  iArray[iCur + 1])	//处理第一节点
	{
		iCur ++;
	}
	else
	{
		iArrayTemp[iCurTemp] = iArray[iCur];
		iCurTemp++;
		iCur++;
	}

	for (;  iCur < len -1; ++iCur)
	{
		if (iArray[iCur] == iArray[iCur - 1] ||iArray[iCur] == iArray[iCur + 1])
		{
			continue;
		}
		else
		{
			iArrayTemp[iCurTemp] = iArray[iCur];
			iCurTemp++;
		}
	}

	if (iArray[iCur] != iArray[iCur - 1] )	//处理最后一个节点
	{
		iArrayTemp[iCurTemp] = iArray[iCur];
		iCurTemp++;

	}

	int iTempLen = iCurTemp;
	pCur = pstrOut;
	pCur->data = iArrayTemp[0];
	pCur->pstrNext = NULL ;

	for (int i = 1; i < iCurTemp ; ++ i )
	{
		strNode *node = new strNode;
		node->data = iArrayTemp[i];
		node->pstrNext =NULL;
		pCur->pstrNext = node;
		pCur = pCur->pstrNext;
	}

	return 0;
}

/* 释放链表 */
void vFreeChan(strNode * pstrChan)
{
    if (NULL == pstrChan)
    {
		return ;
    }
	strNode * pCur = pstrChan;
	strNode * pNext = pstrChan;
	while (NULL != pCur)
	{
		pNext = pCur->pstrNext;
		delete pCur;
		pCur = NULL;
		pCur = pNext;
	}

    return;
}

strNode *vCreatChan(int * piData, int iNum)
{
	int       iLoop         = 0;
	strNode * pstrChanHead  = NULL;
	strNode * pstrChanEnd   = NULL;
	strNode * pstTemp       = NULL;

	if ((NULL == piData) || (iNum < 1))
	{
		return NULL;
	}

	pstrChanHead = (strNode *)malloc(sizeof(strNode));
	pstrChanHead->data     = *piData;
	pstrChanHead->pstrNext = NULL;

	pstrChanEnd = pstrChanHead;

	for (iLoop = 1; iLoop < iNum; iLoop++)
	{
		pstTemp = (strNode *)malloc(sizeof(strNode));
		pstTemp->data = piData[iLoop];
		pstTemp->pstrNext = NULL;

		pstrChanEnd->pstrNext = pstTemp;
		pstrChanEnd = pstrChanEnd->pstrNext;
	}

	return pstrChanHead;
}

int iChanToArray(strNode *pstrChan, int * piData, int * piLenth)
{
	int      iLoop    = 0;
	strNode *pstrTemp = pstrChan;

	if ((NULL == pstrChan) || (NULL == piData) || (NULL == piLenth))
	{
		return -1;
	}

	while(NULL != pstrTemp)
	{
		*(piData + iLoop) = pstrTemp->data;
		pstrTemp = pstrTemp->pstrNext;
		iLoop++;
	}

	*piLenth = iLoop;

	return 0;
}

int main()
{
	strNode * pstrIn  = NULL;
	strNode * pstrOut = NULL;
	int  iLenth  = 0;
	int  iaDataIn[7]    = {6, 7, 8, 8 ,9, 10, 6};
	int  iaDataOut[7]   = {10,9,7};
	int  iaDataMyOut[7] = {0};

	pstrIn = vCreatChan(iaDataIn, 7);
	pstrOut = (strNode *)malloc(sizeof(strNode));
	pstrOut->pstrNext = NULL;
	/* TODO: 调用被测函数 */
	//请考生自己构造单向链表进行测试
	iChanProcess(pstrIn,pstrOut);

	/* TODO: 执行完成后可比较是否是你认为正确的值 */
	iChanToArray(pstrOut, iaDataMyOut, &iLenth);
	//printf("%d\n",pstrOut->data);
	//CPPUNIT_ASSERT(3 == iLenth);
	//CPPUNIT_ASSERT(0 == memcmp((char *)iaDataOut, (char *)iaDataMyOut, sizeof(int) * iLenth));

	/* 释放内存*/
	vFreeChan(pstrIn);
	vFreeChan(pstrOut);
	return 0;
}

时间: 2024-08-24 02:04:17

删除链表中的重复节点、剩余节点逆序输出的相关文章

[华为机试练习题]24.删除链表中的重复节点、剩余节点逆序输出

题目 描述: 题目描述: 输入一个不带头节点的单向链表(链表的节点数小于100),删除链表中内容重复的节点(重复的节点全部删除),剩余的节点逆序倒排. 要求实现函数: void vChanProcess(strNode * pstrIn,strNode * pstrOut); [输入] pstrIn:输入一个不带头节点的单向链表 [输出] pstrOut:删除内容重复的节点(重复的节点全部删除),剩余节点逆序输出(不带头节点,链表第一个节点的内存已经申请). [注意]只需要完成该函数功能算法,中

栈和队列----删除无序单链表中值重复出现的节点

删除无序单链表中值重复出现的节点 给定一个无序单链表的头节点head,删除其中值重复的节点 例如: 1->2->3->3->4->4->2->1->1->null 删除之后变为 1->2->3->4->null 方法1:如果链表长度为N,时间复杂度达到O(N) 方法2:如果要求空间复杂度为O(1),应该怎样实现 [解析] 方法1:利用哈希表去实现 使用哈希表,因为头节点是不用删除的节点,所以首先将头节点放入到哈希表中,然后从下一

删除链表中倒数第n个节点

1.给定一个链表,删除链表中倒数第n个节点,返回链表的头节点. 给出链表1->2->3->4->5->null和 n = 2. 删除倒数第二个节点之后,这个链表将变成1->2->3->5->null. 注意 链表中的节点个数大于等于n 挑战 O(n)时间复杂度 解题思路:刚开始看到倒数第n个节点,不禁感慨如果是数组就可以直接倒着来了.不过针对链表,一定要想起来最常用的方法---快慢指针.设一个fast和slow指针:快指针先走n步,然后快慢指针一起走,

lintcode 容易题:Remove Nth Node From End of Lis 删除链表中倒数第n个节点

题目: 删除链表中倒数第n个节点 给定一个链表,删除链表中倒数第n个节点,返回链表的头节点.  样例 给出链表1->2->3->4->5->null和 n = 2. 删除倒数第二个节点之后,这个链表将变成1->2->3->5->null. 注意 链表中的节点个数大于等于n 解题: 要删除倒数第n个节点,我们要找到其前面一个节点,也就是倒数第n+1的节点,找到这个节点就可以进行删除.和上题的思想很类似, 定义两个指针,p和cur,cur指针向前走,走了n

LintCode Python 简单级题目 174.删除链表中倒数第n个节点

题目描述: 给定一个链表,删除链表中倒数第n个节点,返回链表的头节点. 注意事项 链表中的节点个数大于等于n 您在真实的面试中是否遇到过这个题? Yes 样例 给出链表1->2->3->4->5->null和 n = 2. 删除倒数第二个节点之后,这个链表将变成1->2->3->5->null. 挑战 O(n)时间复杂度 标签 两根指针 链表 题目分析: 创建两个指针,head指向表头.curent指向链表第n个元素: 循环后移n次,直至curent=

LeetCode 19. Remove Nth Node From End of List(删除链表中倒数第N个节点)

题意:删除链表中倒数第N个节点. 法一:递归.每次统计当前链表长度,如果等于N,则return head -> next,即删除倒数第N个节点:否则的话,问题转化为子问题“对head->next这个链表删除倒数第N个节点”,将head的next指针指向该子问题的结果,返回head即可.这个方法时间复杂度高,不推荐. /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next;

如何删除链表中值重复的节点

前言 ??最近在刷<剑指offer>的题,其中有一道题目叫做删除链表中重复的节点,我想了半天没想到比较好的解决办法,于是看了看大佬的解析(菜哭了).不看不知道,一看吓一跳,这尼玛写的也太妙了,忍不住写篇博客记录一下这个解题思路和代码. 题目描述 ??在一个排好序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5. 解题思路 ??这道题我

删除链表中的重复节点

这里的删除是只要有重复就要全部删除,如1->2->2->3,删除之后就是1->3. #include<stdio.h> #include<stdlib.h> struct ListNode { int val; struct ListNode *next; }; struct ListNode* deleteDuplicates(struct ListNode* head) { if(NULL==head||NULL==head->next) retu

删除链表中倒数第k个节点

1. 问题描述 给定一个单链表,删除它的倒数第k个节点.例如给定链表: 1→2→3→4→5,删除它的倒数第二个节点后变为 1→2→3→5.可以假设倒数第k个节点总是存在. 2. 方法与思路 很容易想到第一种方法,就是先对单链表进行进行一次遍历,求出其长度n.然后再进行第二次遍历,设一个指针,向后移动n?k个位置,然后删除这个节点. 第二种方法就是使用双指针,只需要对链表进行一遍访问即可. I. ListNode *p=*q=head II. q指针后移k个位置 III. while q != e