用C语言建立一个顺序存储的线性表并实现线性表的插入和删除操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C语言建立一个顺序存储的线性表并实现线性表的插入和删除操作相关的知识,希望对你有一定的参考价值。
线性表赋值要求采用键盘输入的方式进行赋值。要求完整,可直接运行。... 线性表赋值要求采用键盘输入的方式进行赋值。要求完整,可直接运行。 展开
链表1。是由结构体和指针构成的。
2。包括两个部分一个是数据域和指针域。
3。链表中的结点分为两类:头结点和一般结点。头结点是没有数据域的。
4。基本操作有:初始化链表,增加结点和删除结点,求链表的长度等等。
struct Linknode
int data;
struct Linknode *next;
;
这个地方有个知识点:这个是链表的数据结构是有结构体和指针构成。结构体名为Linknode.但这里面没有定义结构体变量,只有我们定义了结构体变量才能使用结构体。
结构体变量怎么定义呢?
有两种方式:
1。struct Linknode Linklist;
2.typedef struct linknode Linklist.
一般我们都希望采用第2种,这样的好处是: 当我们再定义结构体变量时,可以用:Linklist p;而如果我们采用第一种还必须采用 struct Linknode p;对比一下就可以知道第2种要简单很多。那么下面我们都采用第2种方式来定义结构体变量。
上面我们已经定义了一个链表:
1。初始化链表。
#include
#include
int InitLinkList(Linklist **Lnode)
*Lnode=(Linklist)malloc(sizeof(Linklist));//*Lnode等于L,对与*Lnode的分配空间相当与对主函数中的L分配空间。
if(!*Lnode)
return 0;
(*Lnode)->next=NULL;
在初始化链表的时候,我们用到了2级指针为什么呢?因为我们希望在InitLinkList函数生成的头结点,主函数中也能指向这个头结点。如果我们用一级指针的话,用malloc分配空间的时候,它将会返回分配空间的首地址给指针变量Lnode,而不能使是的空间被主函数中指针变量L得到这个地址。所以我们要用2级指针。
void main()
Linklist *L;
InitLikList(&L);
2。增加链表结点
增加链表结点其实很简单,一般用到三个结构体指针变量和一个循环结构。
InsertLinkList(Linklist *Lnode)
Linklist *p,*q;
int d;
scanf("%d",&d);
if(d==-9999)
break;
p=Lnode->next;//p指向头结点
//通过while循环和指针变量p定位要插入的结点q的位置。
while(p)
p=p->next;
//生成一个要插入的结点
q=(Linklist)malloc(sizeof(Linklist));//申请要插入的结点空间
q->data=d;//填充要插入结点的数据域
q->next=p->next;//首先填充要插入结点q的指针域进行填充。
p->next=q;//然后把定位好的p指针域进行修改指向q.
while(9);//循环退出的条件是输入的数据-9999
void main()
Linklist *L;
InitLinkList(&L);//生成一个头结点
InsertLinkList(L);//插入结点
3。求链表的长度:
int LengthLinkList(Linklist *Lnode)
int i=0;
Linklist *p;
p=Lnode->next;//p指向链表的第一个结点。
while(p)
i++;
p=p->next;
return i;
void main()
Linklist *L;
InitLinkList(&L);//生成一个头结点
InsertLinkList(L);//插入一个结点
LengthLinkList(L)//求链表的长度。
4.删除结点
删除链表结点其实很简单,一般用到三个结构体指针变量和一个循环结构。
DestroyLinkList(Linklist *Lnode)
Linklist *p,*q;
p=Lnode;//p指向链表的头结点
while(p)
q=p->next;//q指向当前结点的下一个结点。
free(p);//释放当前结点
p=q;//p指向下一个结点
void main()
Linklist *L;
InitLinkList(&L);//生成一个头结点
InsertLinkList(L);//插入结点
LengthLinkList(L)//求链表的长度。
DestroyLinkList(L);//删除链表结点
参考技术A 此顺序表实现了多个功能,代码很完善,我将其改成从键盘输入跟选择删除了,你根据你的需要自己再进行修改。
//common.h文件,头文件
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <assert.h>
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100
typedef int datatype;
typedef struct
datatype data[MAXSIZE];
int length;
sqnode, *sqlink;
void creat_sqlist(sqlink *sq);
void set_empty_sqlist(sqlink sq);
int isempty_sqlist(sqlink sq);
int isfull_sqlist(sqlink sq);
int getlength_sqlist(sqlink sq);
datatype getelem(sqlink sq,int i);//i 为第i个元素
int locate_sqlist(sqlink sq, datatype x);//返回该元素在表中的位置
void insert_sqlist(sqlink sq, datatype x, int i);//表示在表中第i个位置前插入。
datatype del_sqlist(sqlink sq, int i);//删除表中第i个元素
void show_sqlist(sqlink sq);
#endif
//线性表实现的c代码
#include "common.h"
void creat_sqlist(sqlink *sq)
*sq = (sqlink)malloc(sizeof(sqnode));
assert(*sq);
bzero(*sq, sizeof(sqnode));
(*sq)->length = 0;
void set_empty_sqlist(sqlink sq)
sq->length = 0;
int isempty_sqlist(sqlink sq)
return sq->length == 0 ? TRUE : FALSE;
int isfull_sqlist(sqlink sq)
return sq->length == MAXSIZE ? TRUE : FALSE;
int getlength_sqlist(sqlink sq)
return sq->length;
datatype getelem(sqlink sq, int i)//i为第i个元素
if(i<1 || i>getlength_sqlist(sq))
printf("i is wrong!\n");
return FALSE;
return sq->data[i-1];
int locate_sqlist(sqlink sq, datatype x)//返回该元素在表中的位置
int j = 1;
while(j <= getlength_sqlist(sq))
if(sq->data[j-1] == x)
return j;
j++;
return FALSE;
void insert_sqlist(sqlink sq, datatype x, int i)//表示在表中第i个位置前插入。
int j = 1;
if(isfull_sqlist(sq))
printf("sqlist is full!\n");
return;
if(i<1 || i>getlength_sqlist(sq)+1)
printf("i is not in the range!\n");
return;
for(j = getlength_sqlist(sq)-1; j>=i-1; j--)
sq->data[j+1] = sq->data[j];
sq->data[i-1] = x;
++sq->length;
datatype del_sqlist(sqlink sq, int i)//删除表中第i个元素
datatype ret;
if(isempty_sqlist(sq))
printf("sqlist is empty!\n");
return FALSE;
if(i<1 || i>getlength_sqlist(sq))
printf("i is not in the range!");
return FALSE;
for(i; i<getlength_sqlist(sq); i++)
sq->data[i-1] = sq->data[i];
--sq->length;
return ret;
void show_sqlist(sqlink sq)
int j = 0;
for(j; j<getlength_sqlist(sq); j++)
printf("%d,",sq->data[j]);
putchar('\n');
//main函数
#include "common.h"
int main (int argc, char *argv[])
int i = 0, n, id;
int num;
printf("你要往顺序表中插入几个元素\n");
scanf("%d", &num);
printf("请往顺序表中插入%d个元素:\n", num);
sqlink sq = NULL;
creat_sqlist(&sq);
while(i < num)
scanf("%d", &n);
insert_sqlist(sq, n, 1);
i++;
printf("顺序表的存储如下:\n");
show_sqlist(sq);
printf("你要删除第几个元素?\n");
scanf("%d", &id);
del_sqlist(sq, id);
printf("删除第%d个元素之后的顺序表为:\n", id);
show_sqlist(sq);
return 0;
数据结构算法C语言实现---2.3线性表的顺序表示和实现
注意:
虽然是用C语言实现,但是考虑到使用了一个C++的特性----引用以简化代码,所以所有的代码均以cpp作为后缀,用g++编译(以后不做说明)。
g++版本:
一.简述
本节主要讲述线性表的顺序实现,主要操作包括建表,插入元素,删除元素,查找元素,合并表等操作,根据书中伪代码编写了C语言,使用int类型进行了测试,需要注意的是查找元素时使用了函数指针,C语言初学者不易理解,可查阅相关书籍学习。
二.头文件
1 //head.h 2 /** 3 My Code 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 /** 8 page 10 9 */ 10 #define TRUE 1 11 #define FALSE 0 12 #define OK 1 13 #define ERROR 0 14 #define INFEASIBLE -1//不可行的 15 #define OVERFLOW -2 16 //Status是函数的类型,其值是函数结果状态代码 17 typedef int Status;//注意分号不能少
三.CPP文件
//2_2.cpp /** author:zhaoyu email:zhaoyu1995.com@gmail.com date:2016-6-4 note:realize my textbook <<数据结构(C语言版)>> */ #include "head.h" //----线性表的动态分配顺序存储结构---- #define LIST_INIT_SIZE 100//线性表存储空间的初始分配量 #define LISTINCREMENT 10//线性表存储空间的分配增量 /** My Code to make the paragram run correctlly */ #define ElemType int typedef struct { ElemType *elem;//存储空间基址 int length;//当前长度 int listsize;//当前分配的存容量(以sizeof(ElemType)位单位) }SqList; int compare(ElemType a, ElemType b) { return a==b?1:0; } /** algorithm 2.3 page 23 */ Status InitList_Sq(SqList &L) { //构造一个空的线性表 L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if (!L.elem) { exit(OVERFLOW); } L.length = 0; L.listsize = LIST_INIT_SIZE; return OK; }//InitList_Sq /** algorithm 2.4 */ Status ListInsert_Sq(SqList &L, int i, ElemType e) { //在顺序线性表L中第i个位置之前插入新的元素e //i的合法为[1, ListLength_Sq(L)+1] if (i < 1 || i > L.length + 1) { return ERROR;//i值不合法 } if (L.length >= L.listsize) {//当前存储空间已满,增加分配 ElemType *newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT)*sizeof(ElemType)); if (!newbase) { exit(OVERFLOW);//存储分配失败 } L.elem = newbase;//新基址 L.listsize += LISTINCREMENT;//增加存储容量 } ElemType *q = &(L.elem[i-1]);//q为插入位置 for (ElemType *p = &L.elem[L.length-1]; p >= q; p--) { *(p+1) = *p;//插入位置及之后的元素右移 } *q = e; ++L.length; return OK; }//ListInsert_Sq /** algorithm 2.5 */ Status ListDelete_Sq(SqList &L, int i, ElemType &e) { //在顺序线性表中删除第i个元素,并用e返回其值 //i的合法值为[1, ListLength_Sq(L)] if ((i < 1) || (i > L.length)) { return ERROR;//i为不合法值 } ElemType *p = &(L.elem[i-1]);//p为被删除元素的位置 e = *p;//被删除的元素赋值给e ElemType *q = L.elem + L.length - 1;//表位元素的位置 for (++p; p <= q; ++p) { *(p-1) = *p;//被删除元素之后的元素左移 } --L.length;//表长减 1 return OK; }//ListDelete_Sq /** algorithm 2.6 */ int LocateElem_Sq(SqList L, ElemType e, Status(* compare)(ElemType, ElemType)) { //在顺序线性表L中查找第1个值与e满足compare()的元素位序 //若找到返回其在L中的位序,否则返回0 int i = 1;//i的初值为第一个元素的位序 ElemType *p = L.elem;//p为第一个元素的存储位置 while (i <= L.length && !(*compare)(*p++, e)) { ++i; } if (i <= L.length) { return i; } else { return 0; } }//LocateElem_Sq /** algorithm 2.7 */ void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) { //已知顺序线性表La和Lb的元素按值非递减排列 //归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列 ElemType *pa = La.elem; ElemType *pb = Lb.elem; Lc.listsize = Lc.length = La.length + Lb.length; ElemType *pc = Lc.elem = (ElemType *)malloc(Lc.listsize*sizeof(ElemType)); if (!Lc.elem) { exit(OVERFLOW); } ElemType *pa_last = La.elem + La.length - 1; ElemType *pb_last = Lb.elem + Lb.length - 1; while (pa <= pa_last && pb <= pb_last) { if (*pa <= *pb) { *pc++ = *pa++; } else { *pc++ = *pb++; } } while (pa <= pa_last) { *pc++ = *pa++; } while (pb <= pb_last) { *pc++ = *pb++; } }//MergeList_Sq /** My code */ void PrintList(SqList L) { for (int i = 1; i <= L.length; i++) { printf("%d\\t", L.elem[i-1]); } printf("\\n"); } /** My Test */ int main(int argc, char const *argv[]) { SqList La, Lb, Lc; InitList_Sq(La); InitList_Sq(Lb); InitList_Sq(Lc); //创建一个1 2 3 4的线性表 ListInsert_Sq(La, 1, 10); ListInsert_Sq(La, 2, 20); ListInsert_Sq(La, 3, 30); ListInsert_Sq(La, 4, 50); PrintList(La); //在位序4(即值为5的位置)插 4 ListInsert_Sq(La, 4, 40); PrintList(La); //创建线性表Lb;10, 20, 5, 30 ListInsert_Sq(Lb, 1, 15); ListInsert_Sq(Lb, 2, 25); ListInsert_Sq(Lb, 3, 5); ListInsert_Sq(Lb, 4, 35); PrintList(Lb); int temp; //删除位置3的元素,并返回给 temp ListDelete_Sq(Lb, 3, temp); PrintList(Lb); printf("%d\\n", temp); //查找 30 在 Lb 的位置 printf("%d\\n", LocateElem_Sq(Lb, 30, compare)); printf("%d\\n", LocateElem_Sq(Lb, 35, compare)); //合并La, Lb 到 Lc,注意前提是有序的 MergeList_Sq(La, Lb, Lc); PrintList(Lc); return 0; }
四.测试
以上是关于用C语言建立一个顺序存储的线性表并实现线性表的插入和删除操作的主要内容,如果未能解决你的问题,请参考以下文章
用C语言编写链式存储结构下实现线性表的创建,插入,删除,按值查找
数据结构实验:线性表的顺序表示和链式表示及插入、删除、查找运算