线性表的链式存储结构——单链表

对于计算机内存而言,能有一片连续的内存空间是非常奢侈的。而线性的顺序表示类似数组的存储方式,需要连续的存储空间。而对于单链表来说,就单个节点的内部是一个整体,就需要占用连续的存储空间;而节点间是通过指针链接起来的,所以说各个节点间的位置是可以不连续的,也可以是连续的,也就是说在空间上是可以不连续的。因此就体现出了链表的优势。

单链表

将链表中各元素分布在存储器的不同存储块称为节点,通过地址或者指针建立他们之间的关系,所得到的存储结构就是链表结构。
单链表的单个节点由一个指针域和数据域组成(头结点数据域不放值,只是一个单纯的指针)。

链表节点类型描述

typedef int data_t;    //用data_t替代int类型
typedef struct node{
	data_t data;    //定义节点的数据域
	struct node *next;   //定义节点的后继指针域
}linklist;

相关的算法操作

linklist *CreateLinklist();//创建头结点 创建空链表

linklist *CreateLinklist(){
	linklist *head = (linklist *)malloc(sizeof(linklist));
	if(head == NULL)
		return NULL;
	head->data = -1;  //因为head的数据域不能放值,我们就指定一个值给它
	head->next = NULL;  //head的下一个节点定为空
	return head;
}

int Linklist_is_empty(linklist * head); //判断链表是否为空

int LInklist_is_empty(linklist *head){
	if(head == NULL)
		return -1;
	return head->next == NULL;
}

int getLengthLinklist(linklist *head); //求链表有效结点的长度(不包含头结点)

int getLengthLInklist(linklist *head){
	if(head == NULL)
		return -1;
	int i = 0;
	linklist *p = head->next;
	for(p){
		i++;
		p = p->next;
	}
	return i;
}

int InsertLinklistBypos(linklist *head,int pos,data_t data); //按位置进行插入

int InsertLinklistBypos(linklist *head,int pos,data_t data){
	if(head == NULL)
		return -1;
	if(pos<0 || pos>getLengthLinklist(head))  //判断插入位置
		return -1;
	//接下来需要创建一个新的节点来作为插入节点
	linklist *new = (linklist *)malloc(sizeof(linklist));
	if(new == NULL)
		return -1;
	new->data = data;    //将插入的值给新节点new的数据域
	new->next = NULL;   //将new的指针域定为空
	//将节点插入链表中
	linkilist *p = head->next;   //重新定义一个变量p,用于遍历
	while(pos--){
		p = p->next;
	}
	new->next = p->next;
	p->next = new;
	return 0;
}

int DeleteLinklistBypos(linklist *head,int pos); //按位置进行删除

int DeleteLinklistBypos(linklist *head,int pos){
if(head == NULL)
		return -1;
	if(pos < 0 || pos > getLengthLinklist(head)-1 || Linklist_is_empty(head))
		return -1;
	linklist *p = head;
	while(pos--)
		p = p->next;
	linklist *q = p->next;

	p->next = q->next;
	free(q);
	q = NULL;
	return 0;
}

int DeleteLinklistBydata(linklist *head,data_t data); //按值进行删除

int DeleteLinklistBydata(linklist *head,data_t data){
	if(head == NULL)
		return -1;
	linklist *p = head;
	linklist *q = NULL;
	while(p){
		//p = p->next;
		if(p->next->data == data)
			break;
		else
		p = p->next;
	}
	q = p->next;
	p->next = q->next;
	free(q);
	q = NULL;
	return 0;
}

data_t SearchLinklistBypos(linklist *head,int pos); //按位置进行查找,返回值

data_t SearchLinklistBypos(linklist *head,int pos){
	if(head == NULL)
		return -1;
	if(pos<0 || pos>getLengthLInklist(head))
		return -1;
	int i = 0;
	linklist *p = head->next;
	while(pos--){
		p = p->next;
	}
	return p->data;
}

linklist * SearchLinklistBydata(linklist *head,data_t data); //按值进行查找,返回位置

linklist *SearchLinklistBydata(linklist *head,data_t data){
	if (head == NULL)
		return -1;
	linklist *p = head->next;
	while(p){
		if(data == p->data)
			break;
		p = p->next;
	}
	return p;
}

int ChangeLinklistBypos(linklist *head,int pos,data_t data);//按位置进行修改

int ChangeLinklistBypos(linkliost *head,int pos,data_t data){
	if(head == NULL)
		return -1;
	if(pos < 0 || pos > getLengthLinklist(head)-1 || Linklist_is_empty(head))
		return -1;
	linklist *p = head->next;
	while(pos--){
		p = p->next;
	}
	p->data = data;
	return 0;
}

int ChangeLinklistBydata(linklist *head,data_t old,data_t new);//按值修改

int ChangeLinklistBydata(linklist *head,data_t old,data_t new)
{
	if(head == NULL)
		return -1;
	linklist *p = head->next;
	while(p){
		if(p->data == old)
			p->data = new;
		p = p->next;
	}
	return 0;
}

int ClearLinklist(linklist *head); //清空链表

int ClearLinklist(linklist *head)    	//清空链表
{
	if(head == NULL)
		return -1;
	linklist *p = head->next;
	linklist *q = NULL;
	while(p != NULL){
		q = p->next;
		free(p);
		p = q;
	}
	head->next = NULL;
	return 0;
}

int destoryLinklist(linklist **head); //摧毁链表(包含头结点)

int destoryLinklist(linklist **head)
{
	ClearLinklist(*head);
	free(*head);
	*head = NULL;
	return 0;
}

int printfLinklist(linklist *head); //打印链表的数据

int printfLinklist(linklist *head)  	
{
	if(head == NULL){
		return -1;
	}
	linklist *p = head->next;
	while(p){
		printf("%3d",p->data);
		p = p->next;
	}
	printf("\n");
	return 0;
}

int daozhi(linklist *head); //将链表倒置

int daozhi(linklist *head){
	if(head == NULL)
		return -1;
	linklist *p = head->next;
	head->next = NULL;
	linklist *q = NULL;
	while(p){
		q = p->next;
		p->next = head->next;
		head->next = p;
		p = q;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <stdio.h> #include <stdlib.h> #define ERROR -1 #define OK 1 //定义单链表 typedef char ElemType; typedef struct LNode // 结点类型定义 { ElemType data; struct LNode * next; }LNode, *LinkList;//LinkList为结构指针类型 //定义关于单链表的若干操作 //初始化--建空表 void InitList(LinkList *L) { *L = (LinkList)malloc(sizeof(LNode)); (*L)->next=NULL; } //尾插法建表 void create_tail(LinkList *L, int n) { LNode *p, *last; int i; last=(*L); for(i=1; i<=n; i++) { p=(LNode *)malloc(sizeof(LNode)); //产生一个新结点 fflush(stdin); //清空内存 scanf("%c", &p->data); //往新结点的数据域中存入元素 last->next=p; //将新结点接在最后一个结点的后面 last=p; //新结点成为最后一个结点 } last->next=NULL; } //求单链表的长度 int ListLength(LinkList L) { LNode *p; int length; p=L->next; //p指针指向第一个元素所在的结点 length=0; //用来存放单链表的长度 while( p!=NULL ) //结点存在 { p=p->next; //p指针向后移 length++; //个数增加1个 } return length; } //求特定元素的个数 int Count(LinkList L, ElemType x) { LNode *p; int length; p=L->next; //p指针指向第一个元素所在的结点 length=0; //用来计算特定元素的个数 while( p ) //结点存在 { if( p->data ==x) //如果找到特定元素,则个数加1 length ++; p=p->next; //p指针向后移 } return length; } //在第i个元素前插入 int ListInsert_L(LinkList *L, int i, ElemType e) { LNode *p, *s; int j; p=(*L); j=0; while( p &&j<i-1) //如果当前结点存在,且移动次数未达到所需次数(找第i-1个结点) { p=p->next; j++; } if(!p || j>i-1) return ERROR; s=(LNode *)malloc(sizeof(LNode)); //产生一新结点 s->data=e; //往新结点中存入元素 s->next=p->next; p->next=s; //新结点接在p结点之后 return OK; } //删除第i个元素 int ListDelete_L(LinkList *L, int i, ElemType *e) { LNode *p,*q; int j; p=(*L); j=0; while(p->next && j<i-1)//(找第i-1个元素)如果当前结点的下一个结点存在,且移动次数未达到所需次数 { p=p->next; j++; } if(!p->next || j>i-1) return ERROR; q=p->next; p->next=q->next; *e=q->data; free(q); //释放要删除的结点 return OK; } void reverse(LinkList *L) { LNode *p,*q,*r; p=(*L)->next; q=p->next; r=q->next; p->next=NULL; while(q!=NULL) { q->next=p; (*L)->next=q; p=q; q=r; if(r!=NULL) r=q->next; else break; } } void main() { LinkList list1; InitList(&list1); create_tail(&list1, 5); LNode *p; for(p=list1->next; p; p=p->next ) printf("%c ",p->data ); printf("\n"); /* printf("\n========================================\n"); printf("\n单链表的长度:%d\n", ListLength(list1)); printf("\n========================================\n"); printf("单链表中元素c的个数:%d\n", Count(list1, 'c')); printf("\n========================================\n"); ListInsert_L(&list1, 3, 'g'); printf("在第3个元素前插入元素g后,单链表中的元素有:\n"); for(p=list1->next; p; p=p->next ) printf("%c ",p->data ); printf("\n"); printf("\n========================================\n"); ElemType e; ListDelete_L(&list1,4, &e); printf("删除第4个元素后,单链表中的元素有:\n"); for(p=list1->next; p; p=p->next ) printf("%c ",p->data ); printf("\n"); printf("删除掉的元素是:%c\n",e); */ reverse(&list1); for(p=list1->next; p; p=p->next ) printf("%c ",p->data ); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值