单链表(不带头结点)

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;

typedef struct Node
{
	ElemType data;
	struct Node *next;
}LNode,*LinkList; 

void InitList(LinkList &l);
void Create_head(LinkList &l);
void Create_rear(LinkList &l);
void Output(LinkList &l);
LNode *Pos(LinkList &l,int i);
void DelList(LinkList &l,int i,ElemType &e);
void InsertList(LinkList &l,int i,ElemType e);
LNode *Get(LinkList &l,ElemType key);
LinkList MergeList(LinkList &La,LinkList &Lb);
int ListLength(LinkList l);

void ShowMenu()
{
    printf("——————————————————————————————\n");
	printf("1、初始化一个单链表\n");
	printf("2、用头插法建立一个单链表\n");
	printf("3、用尾插法建立一个单链表\n");
	printf("4、输出该顺序表\n");
	printf("5、求该单链表的长度\n");
	printf("6、向该顺序表插入元素\n");
	printf("7、对该顺序表删除元素\n");
	printf("8、按值查找\n");
	printf("9、按位置查找\n");
	printf("10、合并两个单链表\n");
	printf("0、退出\n");
    printf("——————————————————————————————\n");
} 

int main()
{
	ShowMenu();
	LinkList l;
	int n;
	while(1)
	{
		printf("请输入你要操作的元素序号:");
		scanf("%d",&n);
		/*if(n==0)
			exit(0);*/
		switch(n)
		{
			case 1:
			{
				InitList(l);
				break;
			}
			case 2:
			{
				printf("请依次输入数据,并以-1作为结束标记:\n");
				Create_head(l);
				break;
			}
			case 3:
			{
				printf("请依次输入数据,并以-1作为结束标记:\n");
				Create_rear(l);
				break;
			}
			case 4:
			{
				Output(l);
				break;
			}
			case 5:
			{
				printf("len:%d\n",ListLength(l));
				break;
			}
			case 6:
			{
				printf("Insert----------------------\n");
				int m,i;
				printf("请依次输入你要插入的位置和元素:");
				scanf("%d %d",&i,&m);
				InsertList(l,i,m);
				break;
			}
			case 7:
			{
				printf("Del--------------\n");
				ElemType e;
				int j;
				printf("请依次输入你要删除的位置:");
				scanf("%d",&j);
				DelList(l,j,e);
				break;
			}
			case 8:
			{
				printf("请输入你要查找的值:");
				int i;
				scanf("%d",&i);
				LNode *q = Get(l,i);
				if(q->next)
					printf("该值的下一个位置的值为:%d\n",q->next->data);
				else
					printf("该值无下一位\n");
				break;
			}
			case 9:
			{
				printf("请输入你要查找的位置:");
				int k;
				scanf("%d",&k);
				LNode *q = Pos(l,k);
					printf("该位置的值为:%d\n",q->data);
				break;
			}
			case 10:
			{
				printf("Merge-----------------\n");
				LinkList l1,l2;
				InitList(l1);
				InitList(l2);
				printf("利用尾插法建立两个有序单链表:\n");
				Create_rear(l1);
				Create_rear(l2);
				LNode *p = MergeList(l1,l2);
				printf("输出合并以后的链表:");
				Output(p);
				break;
			}
			case 0:{
				exit(0);
				break;
			}
			default:{
				printf("非法的数字序号!\n");
			}

		}
	}

	return 0;
} 

void InitList(LinkList &l)
{
	l = NULL;
}

void Create_rear(LinkList &l)
{
	int m;
	LNode *p = NULL;
    while(1)
    {
    	scanf("%d",&m);
        if(m==-1)	break;
        LNode *s= new LNode;
        s->data = m;
        s->next = NULL;
		if(p)
		{
			p->next = s;
			//p = p->next;
		}
		else
		{
			l=s;
		   //p = s;
		}

		p = s;
    }
}

void Create_head(LinkList &l)
{
    int m;
    while(1)
    {
    	scanf("%d",&m);
        if(m==-1)	break;
        LNode *s= new LNode;
        s->data = m;
        s->next = l;
        l = s;
    }
}

LNode *Pos(LinkList &l,int i)
{
	if(i<0)
	{
		printf("非法的寻找位置!\n");
		return NULL;
	}

	if(i==0)
		return l;

	LNode *p = l;
	while(--i)
	{
		p = p->next;
		if(p==NULL)
		{
			printf("寻找位置已超过链表长度\n");
			break;
		}
	}
	return p;
}

void DelList(LinkList &l,int i,ElemType &e)
{
	LNode *p,*q=NULL;
	p = Pos(l,i-1);
	if(p==l)
	{
		l= p->next;
		delete p;
	}
	if(p!=NULL && p->next!=NULL)
	{
		q = p->next;
		p->next = q->next;
		delete q;
	}

}

void InsertList(LinkList &l,int i,ElemType e)
{
	LNode *p,*s;
	p = Pos(l,i);
	s = new LNode;
	s->data = e;
	s->next = p->next;
	p->next = s;
}

LNode *Get(LinkList &l,ElemType key)
{
	Node *p;
	p = l;
	while(p)
	{
		if(p->data != key)
			p = p->next;
		else
			break;
	}

	return p;
}

int ListLength(LinkList l)
{
	LNode *p = l;
	int len=0;
	while(p)
	{
		len++;
		p = p->next;
	}
	return len;
} 

LinkList MergeList(LinkList &La,LinkList &Lb)
{
	LNode *pa,*pb;
	LinkList Lc;

	pa = La;
	pb = Lb;
	Lc = NULL;	

	if(La->data <= Lb->data)
    {
        Lc = La;
        pa = pa->next;
    }
	else
    {
        Lc = Lb;
        pb = pb->next;
    } 

	LNode *r = Lc;	//尾指针
	while(pa &&pb)
	{
		if(pa->data<=pb->data)
		{
			r->next = pa;
			//r = pa;
			pa = pa->next;
		}
		else
		{
			r->next = pb;
			//r = pb;
			pb = pb->next;
		}
           	r = r->next;
            r->next = NULL;
	} 

	if(pa)
		r->next = pa;
	else
		r->next  = pb;

	return Lc;
}

void Output(LinkList &l)
{
    LNode *p;
    p=l;
    while(p)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

时间: 2024-08-29 22:18:42

单链表(不带头结点)的相关文章

C语言实现单链表(带头结点)的基本操作

我在之前一篇博客<C语言实现单链表(不带头结点)的基本操作>中具体实现了不带头结点的单链表的11种操作:如计算链表长度.初始化.创建链表.清空链表等等.但是在实际使用中,带头结点的单链表往往比不带头结点的单链表用的更多,使用也更为方便.因为不用单独考虑第一个节点的情况了,第一个节点和其他后续节点的处理全都一样了,简化操作.这篇博客将会来实现带头结点的单链表的11种操作.代码上传至: https://github.com/chenyufeng1991/LinkedList_HeadNode  .

单链表 使用哑结点避免特殊情况 利大于弊?

哑结点,就是链表的根节点.   一般的, 单链表的插入要考虑空链表的处理, 但如果有哑结点, 就无需这样考虑. 那这样好吗? 如果这样,你需要保证进入插入函数前, 单链表有哑结点,  所以你需要创建,  而且每次操作单链表需要跳过哑结点.   也就是说,  增加哑结点并没有减少特殊情况的处理,  相反, 这些处理分散到其他函数里.     我认为, 为了提高模块的独立性,   应该把空链表处理补上.

链表不带头结点的实现

首先要强调的是,ADT没有变化,只是实现上的变化. 不带头结点的实现比带头结点的实现稍微复杂一些,尤其体现在插入(第58-60行)和删除(第88-91行),要单独处理表头改变的情况.而带头结点的链表表头不会变化,总是指向头结点. 其他操作的不同之处同学们自行比较. 下面的问题会帮助你的理解: 第83行 while(p && j < i - 1) {   而教材上带头结点的实现为while(p->next && j < i - 1) { 为什么会有这种区别?

在不同的数据结构中链表是否带头结点的分析

一.链表 学习数据结构链表的时候,就有区分 带头结点的链表和不带头结点的链表 当时写完带头结点的链表的基本操作算法后,又写了一遍不带头结点的链表的基本操作. 发现是否带头结点的区别主要体现在2个操作的算法上:插入和删除 不带头结点的链表的插入和删除操作因为涉及对第一个结点插入删除,会改变头指针的值,需要对第一个结点单独分析,链表头指针形参上也因此上加入引用或者指针. 所以相对带头结点的链表操作上不带头结点的链表会更加麻烦. 插入算法上的差异: 1 //带头结点的链表 2 int insert(L

单链表一[带头节点链表]

单链表实现分带头节点链表和不带头节点链表: 使用头文件如下: struct LinkNode {     void *x;      struct LinkNode *next; }; 一,带头节点的链表: 1,链表创建 程序说明: 1)函数调用形式:szyu_link_create0("AA", "BB", NULL);其中NULL结尾是在for循环的判断结束条件为x == NULL.使用NULL可以是for循环正常退出 2)程序先创建头节点head,并初始化he

浅谈单链表有头结点和无头节点

有头结点的链表统一了算法的实现,无头节点减少了节点个数,但是只有根据实际情况选用真正的有无头节点链表 待续://代码实现 待续://代码实现 待续://代码实现

单链表(带头节点)

/////////////////////////////////定义节点结构体 struct node{ int data; struct node *pnext;}; ////////////////////////////////////main函数 int main(){ struct node *pHeader = creatList(0); /*insert_tail(creatList(1),pHeader); insert_tail(creatList(2),pHeader);

单链表的创建算法

单链表的创建算法 当一个序列中只含有指向它的后继结点的链接时,就称该链表为单链表. 单链表的示意图如下: Head指针为单链表的头指针,单链表L:L既是单链表的名字,也是其头指针.链表中的最后一个结点的指针域定义为空指针(NULL). 单链表的定义: struct Node { ElemType data; struct Node *next; }; typedef struct Node LNode; typedef struct Node *LinkedList; 单链表有带头结点和不带头结

单链表的基本实现

单链表是方向单一的链表,即就是只能从前向后访问,不能从后向前访问.这篇文章,我 将整理出单链表的一些基本功能. 1.尾插 2.尾删 3.头插 4.头删5.打印 6.插入7.删除指定元素 8.删除指定元素的全部9.删除指 定位置的元素10.排序(此文先给出基本的冒泡排序,其他排序算法之后再给出) 下边,我就这些功能一个一个进行说明,尽量配图~~(这里的单链表不带头结点) 为了方便大家读以下的代码,我给出结构体的定义. typedef struct LinkNode { DataType data;

单链表的反转非递归算法

定义单链表的结点 typedef struct ListNode{ int value; ListNode *next; }ListNode; 我们采用的单链表是带头结点的. 需要遍历一遍链表,在遍历过程中,把遍历的节点一次插入到头部.在这个过程之后,第一个节点成了最后节点,因此要特殊处理,改其后继为NULL. void Inversion(ListNode* head) { if(head->next == NULL) return; //带头结点的单链表,当单链表为空时 if(head->