线性表的基本操作c语言实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表的基本操作c语言实现相关的知识,希望对你有一定的参考价值。

请大虾给一个链式线性表的基本实现操作,有几点要求:
1.输入2.修改3.查找4.删除。
因为书上的都是伪代码,所以想找一个完整的参考学习,无论复制还是自己写的都行,主要是能运行,最好有些注解,新人,什么都不太懂。

代码如下:

头文件:

2_1.h

#ifndef  _2_1_H

#define  _2_1_H

typedef void SeqList;

typedef void SeqListNode;

//创建线性表

SeqList * SeqList_Create(int capacity);

//销毁线性表

void SeqList_DesTroy(SeqList * list);

void SeqList_Clear(SeqList* list);

int SeqList_Length(SeqList* list);

int SeqList_Capacity(SeqList* list);

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);

SeqListNode* SeqList_Get(SeqList* list, int pos);

SeqListNode* SeqList_Delete(SeqList* list, int pos);

#endif

源文件:

// 顺序线性表.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include <malloc.h>

#include <stdlib.h>

#include "2_1.h"

typedef unsigned int TSeqListNode;

typedef struct

int len;     //长度

int capacity;//总长度

TSeqListNode * node;//每个节点的指针

TSeqList;

int main()

SeqList* list = SeqList_Create(5);//创建线性表

int i = 6;//赋值6个变量,已超过线性表最大值 5

int j = 1;

int k = 2;

int x = 3;

int y = 4;

int z = 5;

int index = 0;

SeqList_Insert(list, &i, 7); //将这6个变量插入线性表中

SeqList_Insert(list, &j, 0);

SeqList_Insert(list, &k, 0);

SeqList_Insert(list, &x, 0);

SeqList_Insert(list, &y, 0);

SeqList_Insert(list, &z, 0);

//遍历

for(index=0; index<SeqList_Length(list); index++)

int* p = (int*)SeqList_Get(list, index);

printf("%d  ", *p);

printf("\\n");

//删除操作

while( SeqList_Length(list) > 0 )

int* p = (int*)SeqList_Delete(list, 0);

printf("删除了: %d\\n", *p);

SeqList_Clear(list);

SeqList_DesTroy(list);

system("pause");

return 0;

//创建线性表

SeqList * SeqList_Create(int capacity)

TSeqList* ret = NULL ;

if(capacity >= 0)

ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode)*capacity);  //为线性表分配空间,包含结 //构体和节点的总大小

if(NULL != ret)

ret->len = 0;

ret->capacity = capacity;

ret->node = (TSeqListNode*)(ret + 1);//将节点指向上述分配到的空间的后部分

return ret;

//销毁

void SeqList_DesTroy(SeqList * list)

free(list);

//清空

void SeqList_Clear(SeqList* list)

TSeqList * ret = (TSeqList*)list;

if(NULL != ret)

ret->len = 0;

//获得线性表的长度

int SeqList_Length(SeqList* list)

TSeqList * ret = (TSeqList*)list;

int len = -1;

if(NULL != ret)

len = ret->len;

return len;

//线性表的总长度

int SeqList_Capacity(SeqList* list)

TSeqList * ret = (TSeqList*)list;

int capacity = -1;

if(NULL != ret)

ret->capacity = capacity;

return capacity;

//插入

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)

TSeqList * sList = (TSeqList*)list;

int i,ret = -1;

if((sList != NULL) &&(pos >= 0) && sList->capacity >= sList->len+1)

if(pos >= sList->len)

pos = sList->len;

for(i = sList->len; i > pos; i--)

sList->node[i] = sList->node[i-1];

sList->node[i] = (TSeqListNode)node;

++sList->len;

ret = 1;

return ret;

//获得指定位置的节点

SeqListNode* SeqList_Get(SeqList* list, int pos)

TSeqList * sList = (TSeqList*)list;

TSeqListNode* node = NULL;

if(NULL != sList && pos>=0 && pos < sList->len)

node = (TSeqListNode*)sList->node[pos];

return node;

//删除

SeqListNode* SeqList_Delete(SeqList* list, int pos)

TSeqList * sList = (TSeqList*)list;

SeqListNode * node = SeqList_Get( list, pos);

int i;

if(sList != NULL && pos >= 0 && pos< sList->len)

for( i=pos+1; i<sList->len; i++)

sList->node[i-1] = sList->node[i];

sList->len--;

return node;

演示:

资料拓展:

线性表是最基本、最简单、也是最常用的一种数据结构。

线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。

我们说“线性”和“非线性”,只在逻辑层次上讨论,而不考虑存储层次,所以双向链表和循环链表依旧是线性表。

在数据结构逻辑层次上细分,线性表可分为一般线性表和受限线性表。一般线性表也就是我们通常所说的“线性表”,可以自由的删除或添加结点。受限线性表主要包括栈和队列,受限表示对结点的操作受限制。

线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。

参考技术A #include"stdio.h"
#include<malloc.h>

typedef char ElemType;

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

void CreatListF(LinkList *&L,ElemType a[],int n) //头插法建表

LinkList *s;int i;
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;
for(i=0;i<n;i++)

s=(LinkList *)malloc(sizeof(LinkList));
s->data=a[i];
s->next=L->next;
L->next=s;



void CreateListR(LinkList *&L,ElemType a[],int n) //尾插法建表

LinkList *s,*r;int i;
L=(LinkList *)malloc(sizeof(LinkList));
r=L;
for(i=0;i<n;i++)

s=(LinkList *)malloc(sizeof(LinkList));
s->data=a[i];
r->next=s;
r=s;

r->next=NULL;


void InitList(LinkList *&L) //初始化线性表

L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;


void DestroyList(LinkList *&L) //销毁线性表

LinkList *p=L,*q=p->next;
while(q!=NULL)

free(p);
p=q;
q=p->next;

free(p);


int ListEmpty(LinkList *L) //判断线性表是否为空

return(L->next==NULL);


int ListLength(LinkList *L) //求线性表的长度

LinkList *p=L;int n=0;
while(p->next!=NULL)

n++;p=p->next;

return(n);


void DispList(LinkList *L) //输出线性表

LinkList *p=L->next;
while(p!=NULL)

printf("%c",p->data);
p=p->next;



int GetElem(LinkList *L,int i,ElemType &e) //求线性表中某个数据元素值

int j=0;
LinkList *p=L;
while(j<i&&p!=NULL)

j++;p=p->next;

if(p==NULL)
return 0;
else

e=p->data;return 1;



int LocateElem(LinkList *L,ElemType e) //按元素值查找

LinkList *p=L->next;
int i=1;
while(p!=NULL&&p->data!=e)

p=p->next;i++;

if(p==NULL)return(0);
else return(i);


int ListInsert(LinkList *&L,int i,ElemType e) //插入数据元素

int j=0;
LinkList *p=L,*s;
while(j<i-1&&p!=NULL)

j++;p=p->next;

if(p==NULL)return 0;
else

s=(LinkList *)malloc(sizeof(LinkList));
s->data=e; s->next=p->next; p->next=s;
return 1;



int ListDelete(LinkList *&L,int i,ElemType &e) //删除数据元素

int j=0;
LinkList *p=L,*q;
while(j<i-1&&p!=NULL)

j++;p=p->next;

if(p==NULL)
return 0;
else

q=p->next;
if(q==NULL)return 0;
e=q->data;
p->next=q->next;
free(q);
return 1;



int main()

ElemType e,a[5]='a','b','c','d','e';
LinkList *h;

InitList(h); //初始化顺序表h
CreateListR(h,&a[0],5); //依次采用尾插入法插入a,b,c,d,e元素
printf("单链表为:");
DispList(h); printf("\n"); //输出顺序表h

printf("该单链表的长度为:");
printf("%d",ListLength(h)); printf("\n"); //输出顺序表h的长度
if(ListEmpty(h)) printf("该单链表为空。\n");
else printf("该单链表不为空。\n"); //判断顺序表h是否为空

GetElem(h,3,e);printf("该单链表的第3个元素为:");
printf("%c",e); printf("\n"); //输出顺序表h的第3个元素
printf("该单链表中a的位置为:");
printf("%d",LocateElem(h,'a')); printf("\n"); //输出元素'a'的位置

ListInsert(h,4,'f'); //在第4个元素位置插入'f'素
printf("在第4 个元素位置上插入'f'后单链表为:");
DispList(h); printf("\n"); //输出顺序表h

ListDelete(h,3,e); //删除L的第3个元素
printf("删除第3个元素后单链表为:");
DispList(h); printf("\n"); //输出顺序表h

DestroyList(h); //释放顺序表h
return 0;


这个是我以前做的作业,不知道可以不?本回答被提问者采纳
参考技术B 谭浩强的C语言教程上面有完整的程序 参考技术C // 3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

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

/*构建结点结构体 */
typedef struct LNode
int data;
struct LNode * next;
LNode, * LinkList;
/*用于创建链表的函数 */
/*反序构建的*/
LinkList CreateList_L(LinkList L, int n)

int i;
LinkList p;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
for(i = n; i > 0; --i)

p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next = L->next;
L->next = p;

return L;

/* 用于插入结点的函数 */

LinkList ListInsert_L(LinkList L, int i, int newnode)

LinkList p = L;
LinkList s;
int j = 0;
while(p&&j<i-1)

p = p->next;
++j;

if(!p||j>i-1)

printf("位置小于1或大于表长。\n");
return L;

s = (LinkList)malloc(sizeof(LNode));
s->data = newnode;
s->next = p->next;
p->next = s;
return L;



/* 用于删除结点的函数 */

LinkList ListDelete_L(LinkList L, int i)

LinkList p = L;
LinkList s;
int j=0;
while(p->next&&j<i-1)

p = p->next;
++j;

if(!(p->next)||j>i-1)

printf("删除位置不合理。\n");
return L;

s = p->next;
p->next = s->next;
printf("%s%d\n","被删除的结点是:",s->data);
free(s);
return L;


/*用于遍历链表的函数 */
void ListDisp_L(LinkList L)

LinkList p;
int i=0;
p = L->next;

while(p)

printf("%d:%d\n", ++i,p->data);
p = p->next;




/* 选择排序算法 网上找来的 我自己写的老报错误 */

LinkList ListSort_L(LinkList L)

LinkList h1,p,q,r,s;
h1=p=(LinkList)malloc(sizeof(LinkList));
p->next=L;
while(p->next)

q=p->next;
r=p;
while(q->next)

if(q->next->data < r->next->data)
r=q;
q=q->next;

if(r!=p)

s=r->next;
r->next=s->next;
s->next=p->next;
p->next=s;

p=p->next;

L=h1->next;
free(h1);
return L;


int getoptions()

int opt;
printf("1: 录入链表\n");
printf("2: 显示链表\n");
printf("3: 插入结点\n");
printf("4: 删除结点\n");
printf("5: 排序链表\n");
printf("6: 退出\n");
printf("输入选项并按回车确认:");
scanf("%d",&opt);
return opt;


int main(int argc, char* argv[])

int opt;
int where;
int value;
int count;
LinkList L;
while(1)

system("cls");
opt = getoptions();
if(opt == 1)

system("cls");
printf("请输入链表初始结点数:");
scanf("%d",&count);
printf("请输入各个结点数值,每输入一个按回车确认:\n");
L = CreateList_L(L, count);
system("cls");
ListDisp_L(L);
system("PAUSE");
continue;

if(opt == 2)

system("cls");
ListDisp_L(L);
system("PAUSE");
continue;

if(opt == 3)

system("cls");
ListDisp_L(L);
printf("请输入插入位置:");
scanf("%d", &where);
printf("请输入要插入的数值:");
scanf("%d", &value);
system("cls");
L = ListInsert_L(L,where,value);
ListDisp_L(L);
system("PAUSE");
continue;

if(opt == 4)

system("cls");
ListDisp_L(L);
printf("请输入要删除的位置:");
scanf("%d",&where);
system("cls");
L = ListDelete_L(L,where);
ListDisp_L(L);
system("PAUSE");
continue;

if(opt == 5)

system("cls");
L = ListSort_L(L);
ListDisp_L(L);
system("PAUSE");
continue;

if(opt == 6)

return 0;




数据结构与算法线性表的链式表示和实现,超详细C语言版

链式存储结构

结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻

线性表的链式表示又称为非顺序映像或链式映像。

与链式存储有关的术语

1、结点:数据元素的存储映像。由数据域和指针域两部分组成

2、链表: n 个结点由指针链组成一个链表。它是线性表的链式存储映像,称为线性表的链式存储结构

头指针、头结点和首元结点

头指针 是指向链表中第一个结点的指针

首元结点 是指链表中存储第一个数据元素a1的结点

头结点 是在链表的首元结点之前附设的一个结点;数据域内只放空表标志和表长等信息

讨论

有头结点时,当头结点的指针域为空时表示空表

1. 如何表示空表?

2. 在链表中设置头结点有什么好处?

⒈便于首元结点的处理 首元结点的地址保存在头结点的指针域中,所以在链表的第一个位置上的操作和其它位置一致,无须进行特殊处理;

⒉便于空表和非空表的统一处理
无论链表是否为空,头指针都是指向头结点的非空指针,因此空表和非空表的处理也就统一了。

3. 头结点的数据域内装的是什么?

头结点的数据域可以为空,也可存放线性表长度等附加信息,但此结点不能计入链表长度值。

链表(链式存储结构)的特点

链表的优缺点

优点

缺点

2.5.1 单链表的定义和实现

非空表

空表

  1. 单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名
  2. 若头指针名是L,则把链表称为表L

单链表的存储结构定义

指针变量和结点变量

  • 指针变量p:表示结点地址

  • 结点变量*p:表示一个结点

2.5.2 单链表基本操作的实现

1、初始化




2、取值

思考:顺序表里如何找到第i个元素?

链表的查找:要从链表的头指针出发,顺着链域next逐个结点往下搜索,直至搜索到第i个结点为止。因此,链表不是随机存取结构

3、查找

算法描述


4、插入

算法步骤

算法描述

5、删除


算法步骤

算法描述

链表的运算时间效率分析

1. 查找:

因线性链表只能顺序存取,即在查找时要从头指针找起,查找的时间复杂度为 O(n)。

2. 插入和删除:

因线性链表不需要移动元素,只要修改指针,一般情况下时间复杂度为 O(1)。

但是,如果要在单链表中进行前插或删除操作,由于要从头查找前驱结点,所耗时间复杂度为 O(n) 。

单链表的建立(前插法)

单链表的建立(前插法)

算法描述

单链表的建立(尾插法)

单链表的建立(尾插法)

算法描述

单链表基本操作的代码实现 [C语言]

总功能代码

#include<stdio.h>
#define OK 1 
#define ERROR 0 
#define OVERFLOW -2
#define  MAXSIZE 100     //最大长度

// 定义参数类型
typedef int Status;
typedef int ElemType;

// 定义线性链表存储结构
typedef struct LNode{
     ElemType   data;       //数据域
     struct LNode  *next;   //指针域
}LNode,*LinkList;
// *LinkList为Lnode类型的指针

//初始化(构造一个空表 )
Status InitList_L(LinkList &L)
{
	L = new LNode;
    L->next = NULL;
    return OK;
}

//销毁
Status DestroyList_L(LinkList &L){
	 // 定义指针变量
    LinkList p;
       while(L)
        {
            p=L;  
            L=L->next;
            delete p;  
        }
     return OK;
 }

//清空
Status ClearList(LinkList & L){
  // 将L重置为空表 
   LinkList p,q;
   p=L->next;   //p指向第一个结点
   while(p)       //没到表尾 
      {  q=p->next; delete p;     p=q;   }
   L->next=NULL;   //头结点指针域为空 
   return OK;
 }

//求表长
int  ListLength_L(LinkList L){
//返回L中数据元素个数
    LinkList p;
	int i;
    p=L->next;  //p指向第一个结点
     i=0;             
     while(p){//遍历单链表,统计结点数
           i++;
           p=p->next;    } 
    return i;                             
 }

//判断表是否为空
int ListEmpty(LinkList L){ 
//若L为空表,则返回1,否则返回0 
   if(L->next)   //非空 
     return 0;
   else
     return 1;
 }

//取值(根据位置i获取相应位置数据元素的内容)
//获取线性表L中的某个数据元素的内容
Status GetElem_L(LinkList L,int i,ElemType &e){ 
	LinkList p;
	int j;
    p=L->next;j=1; //初始化
     while(p&&j<i){	//向后扫描,直到p指向第i个元素或p为空 
       p=p->next; ++j; 
     } 
     if(!p || j>i)return ERROR; //第i个元素不存在 
     e=p->data; //取第i个元素 
     return OK; 
}//GetElem_L 


//查找(返回查找元素地址)
//在线性表L中查找值为e的数据元素
LNode *LocateElem_L(LinkList L, ElemType e)
{
    LinkList p;
    p = L->next;
    while (p && p->data != e)
    {
        p = p->next;
        // 返回 L 值为 e 的数据元素的地址,查找失败返回 NULL
        return p;
    }
	return 0;
}

// 查找(返回查找元素序号)
//在线性表L中查找值为e的数据元素
int LocateElem(LinkList L, ElemType e)
{
    LinkList p;
    int j = 1;
    p = L->next;
    while (p && p->data != e)
    {
        p = p->next;
        j++;
    }
    if (p)
    {
        return j;
    }
    else
    {
        return 0;
    }
}

//插入
Status ListInsert(LinkList &L, int i, ElemType e)
{
    LinkList p = L, s;
    int j = 0;
    // 寻找第 i-1 个结点
    while (p && j < i - 1)
    {
        p = p->next;
        ++j;
    }
    // i 大于表长 +1 或者小于 1
    if (!p || j > i - 1)
    {
        return ERROR;
    }
    // 生成新结点 s
    s = new LNode;
    // 将结点 s 的数据域置为 e
    s->data = e;
    // 将结点 s 插入 L 中
    s->next = p->next;
    p->next = s;
    return OK;
}//ListInsert_L 

//删除
Status ListDelete_L(LinkList &L,int i,ElemType &e){
	LinkList p,q;
	int j;
    p=L;j=0; 
    while(p->next &&j<i-1){//寻找第i个结点,并令p指向其前驱 
        p=p->next; ++j; 
    } 
    if(!(p->next)||j>i-1) return ERROR; //删除位置不合理 
    q=p->next; //临时保存被删结点的地址以备释放 
    p->next=q->next; 	//改变删除结点前驱结点的指针域 
    e=q->data; 	//保存删除结点的数据域 
    delete q; 	//释放删除结点的空间 
 return OK; 
}//ListDelete_L 

//单链表的建立(前插法)
void CreateList_F(LinkList &L,int n){ 
	int i;
	LinkList p;
	L=new LNode; 
	L->next=NULL; //先建立一个带头结点的单链表 
	for(i=n;i>0;--i){ 
	p=new LNode; //生成新结点 
	//cin>>p->data; //输入元素值 
	scanf("%d",&p->data);
	p->next=L->next;L->next=p; 	//插入到表头 
     } 
}//CreateList_F 

// // 单链表建立(尾插法)
void CreateList_L(LinkList &L, int n)
{
    LinkList p, r;
    // 正位序输入n 个元素的值,建立带表头结点的单链表L
    L = new LNode;
    L->next = NULL;
    // 尾指针r指向头结点
    r = L;
    printf("please enter element:");
    for (int i = 0; i < n; ++i)
    {
        p = new LNode;
        scanf("%d", &p->data);
        // 插入到表尾
        p->next = NULL;
        r->next = p;
        // r指向新的尾结点
        r = p;
    }
}

//输出
void printList(LinkList L){
	LinkList p;
	p = L->next;
		while(p){
			printf("%d  ",p->data);
			p=p->next;
		}
	printf("\\n");
}

void main(){
	LinkList L;

	ElemType N;

	//初始化
	InitList_L(L);
	
	//单链表的建立(前插法)
	//CreateList_F(L,4);
	//printList(L);

	// 单链表建立(尾插法)
	CreateList_L(L,4);
	//printList(L);
	
	// 插入
	//ListInsert(L,2,3);
	//printList(L);

	//删除
	ListDelete_L(L,2,N);
	printList(L);


	//printf("%d\\n",m);
}

前插

void main(){
	LinkList L;

	//初始化
	InitList_L(L);
	
	//单链表的建立(前插法)
	CreateList_F(L,4);
	printList(L);
}

尾插

void main(){
	LinkList L;

	//初始化
	InitList_L(L);
	
	//单链表的建立(前插法)
	//CreateList_F(L,4);
	//printList(L);

	// 单链表建立(尾插法)
	CreateList_L(L,4);
	printList(L);
	}

插入

void main(){
	LinkList L;

	//初始化
	InitList_L(L);
	
	//单链表的建立(前插法)
	//CreateList_F(L,4);
	//printList(L);

	// 单链表建立(尾插法)
	CreateList_L(L,4);
	//printList(L);
	
	// 插入
	ListInsert(L,2,3);
	printList(L);
	}

在位置2插入数字3

删除

void main(){
	LinkList L;

	ElemType N;

	//初始化
	InitList_L(L);
	
	//单链表的建立(前插法)
	//CreateList_F(L,4);
	//printList(L);

	// 单链表建立(尾插法)
	CreateList_L(L,4);
	//printList(L);
	
	// 插入
	//ListInsert(L,2,3);
	//printList(L);

	//删除
	ListDelete_L(L,2,N);
	printList(L);


	//printf("%d\\n",m);
}

取值(根据位置i获取相应位置数据元素的内容)

void main(){
	LinkList L;

	ElemType N;

	//初始化
	InitList_L(L);
	
	//单链表的建立(前插法)
	//CreateList_F(L,4);
	//printList(L);

	// 单链表建立(尾插法)
	CreateList_L(L,4);
	//printList(L);

	//取值(根据位置i获取相应位置数据元素的内容)
	GetElem_L(L,2,N);
	printf("%d\\n",N);
	}

查找

求表长

printf("链表长度为:%d\\n\\n", ListLength_L(L));

清空、销毁链表、判断是否为空

//判断表是否为空
    ListEmpty(L);

	//清空链表
	ClearList(L);
	printf("清空链表之后,");
	printf("%d\\n",ListEmpty(L));
	//销毁链表
	if(DestroyList_L(L)){
		printf("链表销毁成功!\\n");
	}

2.5.3 循环链表

持续更新中

以上是关于线性表的基本操作c语言实现的主要内容,如果未能解决你的问题,请参考以下文章

数据结构算法C语言实现---2.3线性表的顺序表示和实现

C语言数据结构 线性表的基本功能实现

数据结构c语言版 使用线性表的顺序储存结构定义(静态)实现线性表的初

数据结构与算法线性表的重要基本操作与代码实现C语言版

请教会C语言的高人线性顺序表问题

用C语言建立一个顺序存储的线性表并实现线性表的插入和删除操作