单链表的建立(头部延长、尾部延长)、插入操作、删除操作(无头结点的删除、有头结点的删除)

这里简单的介绍了单向链表的创建,链表的冒泡排序法和链表的输出

以下是在头部插入时进行的操作

头部插入示意图如下:


#include "stdafx.h"
#include <stdlib.h>

struct node  //节点的定义
{
	int data;
	struct node * next;
};

void print(struct node *head)//链表的输出函数
{
	struct node *ptr = head;
	while (ptr != NULL)
	{
		printf("%d ", ptr->data);
		ptr = ptr->next;
	}
	printf("\n");
}

void order(struct node *head, int count) //链表的冒泡排序
{
	struct node *ptr, *next;
	int t;
	for (int i = 0; i<count; i++)  
	{
		
		ptr = head;
		next = ptr->next;
		for (int j = count - i - 1; j>0; j--)
		{
			if (ptr->data > next->data)
			{
				t = ptr->data;
				ptr->data = next->data;
				next->data = t;
			}
			ptr = ptr->next;
			next = next->next;
		}
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	int input,count=0;
	struct node * head, *temp;
	head = NULL;
	printf("请输入数据,输入0表示结束:\n");
	while (1)
	{
		temp = (struct node *)malloc(sizeof(struct node));//为每个节点分配空间
		scanf_s("%d", &input);

		if (input == 0) break;
		temp->data = input;//链表的初始化
		//temp->next = NULL;

                temp->next = head;//在头部方向延长链表
		head = temp;

		count++;  //节点的总数
	}

	printf("排序前结果:\n");
	print(head);
	order(head, count);	
	printf("排序后结果:\n");
	print(head);
	scanf_s("%d", &input);
	return 0;
}


以下是在尾部插入时进行的操作,在上面的基础上进行了少许修改。

尾部插入示意图如下:


</pre><p><pre name="code" class="html">// 链表.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>

struct node  //节点的定义
{
	int data;
	struct node * next;
};

void print(struct node *head)//链表的输出函数
{
	struct node *ptr = head->next;//跳过头结点进行输出
	while (ptr != NULL)
	{
		printf("%d ", ptr->data);
		ptr = ptr->next;
	}
	printf("\n");
}

void order(struct node *head, int count) //链表的冒泡排序
{
	struct node *ptr, *next;
	int t;
	for (int i = 0; i<count; i++)
	{

		ptr = head;
		next = ptr->next;
		for (int j = count - i - 1; j>0; j--)
		{
			if (ptr->data > next->data)
			{
				t = ptr->data;
				ptr->data = next->data;
				next->data = t;
			}
			ptr = ptr->next;
			next = next->next;
		}
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	int input, count = 1;//从1开始,不计头结点
	node * head, *temp,*end;
	printf("请输入数据,输入0表示结束:\n");

	end = (node *)malloc(sizeof(node));
	head = end;
	//head->next = NULL;//建立空表头,系统会随机分配一个数据值

	while (1)
	{
		
		temp = (node *)malloc(sizeof(node));//开辟新节点
		scanf_s("%d", &input);
		if (input == 0) break;

		temp->data = input;//赋值
		temp->next = NULL;//不能省略

		end->next = temp;//新节点挂在尾部
		end = temp;	//新节点成为新的尾部标志
		
		count++;  //节点的总数
	}
	
	printf("排序前结果:\n");
	print(head);
	order(head, count);
	printf("排序后结果:\n");
	print(head);
	scanf_s("%d", &input);
	return 0;
}

//插入操作
void insert(NODE *head, int x, int i)
{
  NODE *p,*s;
  int count=0;
  p=head;
  while(count<i-1)
  {p=p->next; count++}
  s=malloc(sizeof(NODE));
  s->data=x;
  s-next=p->next;
  p-next=s;
}

题目:

        假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个节点(非第一个节点, 也非最后一个节点)。请将该节点从单链表中删除。


解答:

        典型的“狸猫换太子”, 若要删除该节点,正常情况下,应该要知道该节点的前面节点的指针,但是由于单链表中没有头结点,所以无法追溯到该节点前面的那个节点,因此,这里采用了“移花接木”的方法。设该节点为B,下一个节点为C。那么,首先将B节点的内容替换为C节点的内容,然后,将C节点删除,这样就达到了我们的目的。代码如下:


pcur->next = pnext->next;

pcur->data = pnext->date;

delete pnext;
代码:

void DeleteListNode(node* pCurrent)  
{      
 assert(pCurrent != NULL);      
 node* pNext = pCurrent -> next;     
 if (pNext == NULL)      
  pCurrent = NULL;    
 else  
 {     
  pCurrent -> next = pNext -> next;  
  pCurrent -> data = pNext -> data;   
  delete pNext;     
 }
}

对于有头结点的单链表可用如下方法进行删除

void RemoveNode(Node *&head, int target) 
{ 
    //找到节点target的前驱节点  
    Node *curr = head->pNext; 
    Node *pre = head; 
    while (curr != NULL ) 
    { 
        if (curr->pos == target) 
        { 
            break; 
        } 
        else 
        { 
            pre = curr; 
            curr = curr->pNext; 
        } 
    } 
 
    //删除节点  
    pre->pNext = curr->pNext; 
    curr->pNext = NULL; 
} 




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值