C语言实现数据结构---顺序表,单链表

线性表分为:顺序存储结构和连存储结构

顺序存储结构的优点:

1.空间利用率高,几乎不需要额外的空间开销.

2.数据的逻辑结构和物理结构完全一致.

3.结点地址计算的时间和线性表的规模大小无关.

4.可以用一维数组实现存储.

但是有两个缺点:

 1.顺序存储结构的存储空间是静态分配,必须有足够大的连续存储空间,如果不能则无法实现存储.在建立顺序表时,存储空间大小有时无法确切估计,估计过大回会使空闲区段的部分空间长期闲置,估计过小则会在操作中因空间不够而产生溢出.

2.插入操作和产出操作在大多数情况下,引起大量节点的频繁移动,降低了算法的时间效率.

因此:顺序存储结构 比较适合规模较小,长度变化不大且不很频繁的线性表存储实现.

克服线性表顺序存储结构的方法采用链表存储结构,链表存储结构的存储分配方式灵活,有效性好.用链表存储结构存储的线性表称为"链表".

代码实现--------顺序表

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

#define OK 0
#define OVERFLOW 1
#define ERROR -1

#define TURE 1
#define FALSE 0

#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10

typedef int ElemType;
typedef int Status;

typedef struct
{
	ElemType *elem;   //存储空间基址 
	int length;       //当前长度 
	int listsize;     //当前分配的存储容量(以sizeof(ElemType)为单位) 
}SqList;

Status InitList_Sq(SqList &L)
//构造一个空的线性表L 
{
	L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
	if(!L.elem) return OVERFLOW;
	L.length=0;
	L.listsize=LIST_INIT_SIZE;
	return OK;
}
Status ListInsert_Sq(SqList &L,int i,ElemType e)
//在顺序线性表L中第i个位置之前插入新的元素e 
//i的合法值为1<=i<=ListLength.Sq(L)+1 
{
	ElemType* newbase, * q, * p;
	if(i<1||i>L.length+1) return ERROR;
	if(L.length>=L.listsize)
	{
		newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
		if(!newbase) exit (OVERFLOW);
		L.elem=newbase;
		L.listsize+=LISTINCREMENT;
	}
	q=&(L.elem[i-1]);
	for(p=&(L.elem[L.length-1]);p>=q;--p)
	*(p+1)=*p;
	*q=e;
	++L.length;
	return OK;
} 

Status ListDelete_Sq(SqList &L,int i,ElemType e)
//在顺序线性表中删除第i个元素,并用e返回其值 
{
	ElemType * q, * p;
	if((i<1)||(i>L.length)) return ERROR;
	p=&(L.elem[i-1]);
	e=*p;
	q=L.elem+L.length-1;
	for(++p;p<=q;++p)
	*(p-1)=*p;
	--L.length;
	return OK; 
}

Status Input(SqList &L,int n)
//输入函数 
{
	int i,m;
	printf("请输入各元素的值:\n");
	while(n--)
	{
		scanf("%d",&m);
		ListInsert_Sq(L,L.length+1,m);
	}
}

Status Output(SqList &L)
//输出函数 
{
	int i;
	for(i=0;i<L.length;i++)
	printf("%d\t",L.elem[i]);
	printf("\n");
}

int main()
{
	int i,n;	
	SqList L;
	ElemType e;
	InitList_Sq(L);
	printf("请输入顺序表长度:\n");
	scanf("%d",&i);
	//L.length=i;
	Input(L,i);
	
	while(1)
	{
		system("cls");
		Output(L);
		printf("1.插入元素  2.删除元素\n");
		scanf("%d",&n);
		if(!n) break;
		else if(n==1)
		{
			system("cls");
			while(1)
			{
				Output(L);
				printf("请输入要插入的位置或输入0返回上一级\n"); 
				scanf("%d",&n);
				if(!n) break;
				system("cls");
				Output(L);
				printf("请输入要插入的元素值:\n");
				scanf("%d",&i);
				//ListInsert_Sq(L,n,i);
				system("cls");
				if(!ListInsert_Sq(L,n,i))
				{
					printf("操作成功\n");
				}
				else
				{
					printf("操作失败\n");
				}
			}
			
		}
		else if(n==2)
		{
			system("cls");
			while(1)
			{
				Output(L);
				printf("请输入要删除的位置或输入0返回上一级\n");
				scanf("%d",&n);
				//ListDelete_Sq(L,n,e);
				if(!n) break;
				system("cls");
				if(!ListDelete_Sq(L,n,e))
				{
					printf("删除成功\n"); 
				}
				else
				printf("删除失败\n"); 
			}
		}
		
	}
	return 0; 
}

代码实现--------单链表

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include <iostream>
using namespace std;

#define OK 1
#define ERROR 0
#define TURE 1
#define FALSE 0
#define  OVERFLOW  -1

typedef int Status;
typedef int ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode *next;

} LNode,*Linklist;

//创建单链表
 void CreateList_L(Linklist &L,int n){
     //逆序输入n个元素的值,建立带表头节点的单链表L
     L=(Linklist)malloc(sizeof(LNode));
     L->next=NULL;   //  先建立一个带头结点的单链表
    int i;
    Linklist p;
	cout<<"请输入元素值:"<<endl;
    for(i=n;i>0;--i){
         p=(Linklist)malloc(sizeof(LNode));//生成新节点 
                
            cin>>p->data;
         p->next=L->next;L->next=p; //插入到表头 
     }
 } 

//获取第i个元素的值 
Status GetElem_L(Linklist L,int i,ElemType &e) {
	//L为带头节点的单链表头指针
	//当第i个元素存在时,其值赋给e,返回OK,否则返回ERROR
	Linklist p;
	p = L->next;
	int j = 1;
	//初始化 p指向第一个结点,j计数
	while (p&&j < i) {//顺时针查找
		p = p->next;
		++j;
	}
	if (!p || j > i) {
		return ERROR;
	}
	e = p->data;
	return OK;

}
Status	ListInsert_L(Linklist &L, int i, ElemType e) {
	//在带头节点在单链线性表L中第i个位置之前插入元素e
	Linklist p;
	p = L;
	int j = 0;
	while (p&&j<i-1) {
		p = p->next;
		++j; //找到第i-1个节点
	}
	if (!p || j > i - 1) return ERROR;
	Linklist s;
	s = (Linklist) malloc(sizeof(LNode));	//生成新节点s
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}
Status ListDelete_L(Linklist &L, int i, ElemType &e) {

	//删除第i个元素,返回其值    p->next = p->next->next
	Linklist p;
	p = L;
	int j = 0;
	while (p->next && j < i - 1) {
		p = p->next;
		++j;
	}
	if (!(p->next) || j > i - 1) return ERROR;
	Linklist q;
	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	return OK;
}
void showL(Linklist L){
	Linklist p;
    p=L->next;
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
}
}
int main() {	
	Linklist L;
    CreateList_L(L,5) ;//创建长度5的单链表 
    
    cout<<"此时的单链表:\n";
    showL(L);
    cout<<"\n"; 
    int n;
 cout<<"请输入要插入的元素:"<<endl;
	cin>>n;
	ListInsert_L(L,1,n);
	cout<<"插入后的链表:"<<endl;
	 showL(L);
	 cout<<"\n"; 
	 int i,e;
	 cout<<"请输入要删除的第几个元素:"<<endl; 
	 cin>>i;
	  ListDelete_L(L,i,e);
	  cout<<"删除后的链表:"<<endl; 
	  showL(L);

}






发布了43 篇原创文章 · 获赞 6 · 访问量 1537

猜你喜欢

转载自blog.csdn.net/weixin_43729631/article/details/102649824
今日推荐