链表--基本算法

#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;
typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode, *pLinkNode;

typedef struct LinkList
{
	pLinkNode pHead;
}LinkList,*pLinkList;

void InitLinkList(pLinkList list);
void DestoryList(pLinkList list);
void PushBack(pLinkList list , DataType x);
void PopBack(pLinkList list);
void PushFront(pLinkList list , DataType x);
void PopFront(pLinkList list);
void PrintList(pLinkList list);
pLinkNode Find(pLinkList list,DataType x);
void Insert(pLinkList list, pLinkNode pos, DataType x);
void Remove(pLinkList list, DataType x);
void RemoveAll(pLinkList list, DataType x);
void Erase(pLinkList list,pLinkNode pos);
void BubbleSort(pLinkList list);
void SelectSort(pLinkList list);
void InsertSort(pLinkList list);

#endif //__LINKLIST_H__

#include"linklist.h"

void CreateNode(pLinkNode *newNode, DataType x)
{

	*newNode = (pLinkNode)malloc(sizeof(LinkNode));
	if (NULL == *newNode)
	{
		printf("out of memory\n");
		exit(EXIT_FAILURE);
	}
	(*newNode)->data = x;
	(*newNode)->next = NULL;
}
void InitLinkList(pLinkList list)
{
	assert(list);
	list->pHead = NULL;
}

void DestoryList(pLinkList list)
{
	assert(list);
	if (NULL==list->pHead)            //空链表直接返回
	{
		return;
	}
	else
	{
		pLinkNode cur = list->pHead;     //cur指向第一个结点
		while (cur != NULL)
		{
			list->pHead = cur->next;    //pHead指向cur的下一个结点,当cur是最后一个结点时,pHead指向空
			free(cur);
			cur = list->pHead;          //cur指向当前第一个结点,当链表为空时,cur指向空
		}
	}

}

void PushBack(pLinkList list, DataType x)
{
	assert(list);
	pLinkNode newNode = NULL;
	CreateNode(&newNode,x);
	if (NULL == (list->pHead))             //如果是空链表,直接插入头指针之后
	{
		list->pHead = newNode;
	}
	else
	{
		pLinkNode cur = list->pHead;
		while (NULL != (cur->next))            //找到最后一个结点cur
		{
			cur = cur->next;
		}
		cur->next = newNode;
	}
}

void PopBack(pLinkList list)
{
	assert(list);
	if (NULL == list->pHead)
	{
		return;
	}
	else
	{
		pLinkNode cur = list->pHead;
		if (NULL == cur->next)                 //如果只有一个结点
		{
			free(cur);
			list->pHead= NULL;
		}
		else
		{
			while (NULL != cur->next->next)         //大于一个结点,先找到倒数第二个结点
			{
				cur = cur->next;
			}
			free(cur->next);
			cur->next= NULL;
		}
	}
}

void PushFront(pLinkList list, DataType x)
{
	assert(list);
	pLinkNode newNode = NULL;
	CreateNode(&newNode, x);
	newNode->next =list->pHead;           //newNode的指针域先指向第一个结点
	list->pHead= newNode;                 //头指针指向newNode
}

void PopFront(pLinkList list)
{
	assert(list);
	if (NULL == list->pHead)              //空链表
	{
		return;
	}
	pLinkNode cur = list->pHead;         //cur指向第一个结点
	list->pHead = cur->next;             //指向第一个结点的指针域
	free(cur);
	cur = NULL;
}

void PrintList(pLinkList list)
{
	assert(list);
	pLinkNode cur = list->pHead;
	while (NULL != cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("over\n");
}

pLinkNode Find(pLinkList list, DataType x)
{
	assert(list);
	pLinkNode cur = list->pHead;
	while (NULL != cur)
	{
		if (cur->data == x)
		{
			break;
		}
		cur = cur->next;
	}
	return cur;
}

void Insert(pLinkList list, pLinkNode pos, DataType x)  //在pos后面插入元素
{
	assert(list);
	pLinkNode newNode = NULL;
	CreateNode(&newNode, x);
	pLinkNode cur = list->pHead;
	while (NULL != cur)                                  //先找到这个位置
	{
		if (cur == pos)
		{
			break;
		}
		cur = cur->next;
	}
	if (NULL != cur)
	{
		newNode->next=cur->next;
		cur->next = newNode;
	}
	else
	{
		printf("没有这个结点\n");
	}

}

void Remove(pLinkList list, DataType x)
{
	assert(list);
	pLinkNode cur = list->pHead;
	pLinkNode p = list->pHead;
	if (NULL == list->pHead)              //空链表直接返回
	{
		return;
	}
	if (NULL == cur->next)                 //如果只有一个结点
	{
		if (cur->data == x)
		{
			list->pHead = cur->next;
			free(cur);
			return;
		}
	}
	else
	{
		if (cur->data == x)                   //先判断第一个结点是不是要删除的结点
		{
			list->pHead = cur->next;
			free(cur);
			return;
		}
		cur = cur->next;
		while (NULL != cur)
		{
			if (cur->data == x)
			{
				p->next = cur->next;   //p结点的指针域指向要删除结点的指针域
				free(cur);
				return;
			}
			p = cur;
			cur = cur->next;
		}
	}
}

void RemoveAll(pLinkList list, DataType x)
{
	assert(list);
	pLinkNode cur = list->pHead;
	pLinkNode p = NULL;
	if (NULL == list->pHead)
	{
		return;
	}
	while (NULL != cur)
	{
		if (NULL == list->pHead->next)          //如果要只有一个结点
		{
			if (cur->data == x)                 //如果是则删除
			{
				list->pHead = cur->next;
				free(cur);
				return;
			}
		}
		else if (list->pHead->data == x)         //判断是不是第一个结点,是则删除,继续判断
		{
				list->pHead = cur->next;
				free(cur);
				cur = list->pHead;
		}
		else
		{
			break;
		}
	}
	//要删除的结点在第一个结点之后
	cur = cur->next;
	p = list->pHead ;
	while (NULL != cur)
	{
		if (cur->data == x)
		{
			p->next = cur->next;           //p结点的指针域指向要删除结点的指针域
			free(cur);
			cur = p;
		}
		p = cur;
		cur = cur->next;
	}
}

void Erase(pLinkList list, pLinkNode pos)   //删除pos后面的结点
{
	assert(list);
	pLinkNode cur = list->pHead;
	pLinkNode p = list->pHead;
	if (NULL == cur)
	{
		return;
	}
	if (NULL == cur->next)                  //如果只有一个结点
	{
		if (cur == pos)
		{
			free(cur);
			list->pHead = NULL;
		}
	}
	else
	{
		if (cur == pos)                        //如果是第一个结点
		{
			list->pHead = cur->next;
			free(cur);
			return;
		}
		cur = cur->next;
		while (NULL != cur)
		{
			if (cur == pos)
			{
				p->next = cur->next;
				free(cur);
				return;
			}
			p= cur;
			cur = cur->next;
		}
	}
}

void BubbleSort(pLinkList list)
{
	assert(list);
	pLinkNode cur = list->pHead;
	pLinkNode p1= list->pHead;
	int flag = 0;
	DataType tmp=0;
	if (NULL == list->pHead)
	{
		return;
	}
	if (NULL == cur->next)
	{
		return;
	}
	pLinkNode p2 = list->pHead->next;
	cur = cur->next;
	while (NULL!=cur)
	{
		flag = 1;
		while (NULL != p2)
		{
			if (p1->data > p2->data)
			{
				tmp = p1->data;
				p1->data = p2->data;
				p2->data = tmp;
				flag = 0;
			}
			p2 = p2->next;
			p1 = p1->next;
		}
		if (flag)
		{
			break;
		}
		p1 = list->pHead;
		p2 = list->pHead->next;
	    cur = cur->next;
	}
}

#include"linklist.h"
void Menu()
{
	printf("**********************************\n");
	printf("*0.Quit           1.InitLinkList *\n");
	printf("*2.PushBack       3.PopBack      *\n");
	printf("*4.PushFront      5.PopFront     *\n");
	printf("*6.PrintList      7.Find         *\n");
	printf("*8.Insert         9.Remove       *\n");
	printf("*10.RemoveAll     11.Erase       *\n");
	printf("*12.BubbleSort    ****************\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n");
	printf("请选择:> ");
}

void test()
{
	LinkList list;
	DataType x = 0;
	pLinkNode pos = NULL;
	int n = -1;
	while (1)
	{
		Menu();
		scanf("%d", &n);
		switch (n)
		{
		case 0:
			DestoryList(&list);
			exit(1);
			break;
		case 1:
			InitLinkList(&list);
			break;
		case 2:
			printf("请输入:>");
			scanf("%d",&x);
			PushBack(&list,x);
			break;
		case 3:
			PopBack(&list);
			break;
		case 4:
			printf("请输入:>");
			scanf("%d", &x);
			PushFront(&list,x);
			break;
		case 5:
			PopFront(&list);
			break;
		case 6:
			PrintList(&list);
			break;
		case 7:
			printf("请输入:>");
			scanf("%d", &x);
			pos=Find(&list,x);
			printf("查找成功\n");
			break;
		case 8:
			printf("请输入元素:>");
			scanf("%d", &x);
			Insert(&list,pos,x);
			break;
		case 9:
			printf("请输入:>");
			scanf("%d", &x);
			Remove(&list,x);
			break;
		case 10:
			printf("请输入:>");
			scanf("%d", &x);
			RemoveAll(&list,x);
			break;
		case 11:
			Erase(&list,pos);
			break;
		case 12:
			BubbleSort(&list);
			break;
		default:
			printf("选择无效,请重新选择\n");
			break;
		}
	}
}

int main()
{
	test();
	system("pause");
	return 0;
}

时间: 2024-08-03 10:38:50

链表--基本算法的相关文章

集合框架之链表集合算法

链表集合算法: 1.链=引用 2.链表集合与数组集合的区别:在增值方面,数组集合的速度比链表集合算法[学Java,到凯哥学堂kaige123.com]的速度要快:但是链表集合在增删值和修改值方面要更灵活,它的原理就好比链条. 3.链表的分类: 3.1单链集合(了解即可):上家能找到下家,但是下家找不到上家,即通过上一个数组可以找到下一个数组,但是没办法通过下一个数组找到上一个数组.如下图: 3.2双链集合:上家能找到下家,下家也能找到上家.如下图: 4.代码实现(以双链为例): 4.1添加值 4

链表创建和链表遍历算法的演示_C语言

今天搞了一个多小时,头是疼的,应该是没休息好吧,学习了数据结构这一节,感觉收益良多,下面贴上代码和心得: 1 /*24_链表创建和链表遍历算法的演示*/ 2 # include <stdio.h> 3 # include <malloc.h> 4 # include <stdlib.h> 5 6 typedef struct Node 7 { 8 int data;//数据域 9 struct Node * pNext;//指针域 10 }NODE, *PNODE;//

单向链表反转算法——递归版和迭代版

最近在做笔试题时,遇到一道编程题:单向链表反转算法.一时紧张,没写出来就提前交卷了,然而交完卷就想出来了... 最初想出来的是递归版,遗憾的是没能做到尾递归,后来又琢磨出了迭代版.后来用实际编译运行测试了一遍,能正常运行. 递归版的灵感来源于<Haskell 趣学指南>中非常简洁的快速排序算法的实现,其思想是将单向链表分割头部和尾部.其中头部指是链表的第一个节点,尾部是指除去第一个节点后的子链表.通过递归的方法,将子链表继续分割成头部和尾部,直至尾部指剩下一个节点,无法继续分割,然后将头部和尾

链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习

单链表的算法设计

当学习完单链表后,仔细回忆回忆,单链表还是很容易掌握的,但是还是要仔细认真的品味. 单链表可以看做是由若干个结点由指针指向后继结点一种表.结点是由数据域和指针域构成.真正有效的存储是数据域,指针域负责指向下一个结点存储的位置,所以它的存储密度都是小于1,而之前学习的顺序表存储密度都是1.那么如何定义结构体 12345 typedef struct { Eletype data; struct *next;//指针域}node,*Node; 那么单链表具体可以做些什么操作哪? 初始化操作,主要是对

单链表倒置算法

LinkList reverse(LinkList L)//单链表的倒置算法 { LNode *p,*q; p=L->next; L->next=NULL; while(p) { q=p; p=p->next; q->next=L->next; L->next=q; } return L; }

链表高级算法——2

一.判断两个链表是否相交 int CheckCross(pLinkList list1, pLinkList list2) //判断链表是否相交 { assert(list1); assert(list2); pLinkNode cur1 = list1->pHead; pLinkNode cur2 = list2->pHead; if ((NULL==list1->pHead)||(NULL==list2->pHead)) { return -1; } while (NULL!=

链表面试题(一):反转链表的算法实现

关于链表的考察 链表是面试里面经常涉及到的考点,因为链表的结构相比于Hashmap.Hashtable.Concurrenthashmap或者图等数据结构简单许多,对于后者更多面试的侧重点在于其底层实现.比如Hashmap中Entry<k,v>等操作.如何扩容.容量的设定等.链表的考察更侧重于代码的书写和思路的形成.虽然说,链表的结构简单,但是涉及到指针的操作,容易引申出一些挑战性的考题,其中也牵涉到诸多小的细节的考虑,更能看出代码书写的能力和功底. 面试题:反转链表 题目:定义一个函数,输入

单链表的算法

要点 单链表的结构可表示如下: typedef int ElemType; typedef struct LNode { ElemType data; struct LNode* next; } LNode, *LinkList; 基本算法 插入结点 假设要在单链表的a结点和b结点之间插入一个值为x的新结点. 如下图所示,指针s指向一个值为x的结点,为了插入s. 首先让s的next指针指向b,即s->next = p->next; 然后,让a的next指针指向s,即p->next = s

链表相关算法题总结 1

链表题目对算法的要求度不高,但实际写的过程中需要注意语言细节,考虑精细度的地方很多. 1.链表结构与基本操作 1.1 添加节点 一般情况: cur ->next = prev ->next; prev ->next = cur; 表头插入: cur ->next = head; head = cur; 1.2删除节点 一般情况:(已知待删除节点的前驱节点) ListNode* temp = prev->next; prev->next = prev->next-&