顺序表代码
单链表代码
循序表算法
#include<stdio.h>
#include<string.h>
#include"malloc.h"
# define MaxSize 100
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
#define LIST_INCREMENT 10 // 线性表存储空间的分配增量
typedef struct {
ElemType *elem; // 存储空间基址
int length; // 当前长度
int listsize; // 当前分配的存储容量
} SqList;
int list_initialize(SqList &L)
{
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(L.elem ==NULL) return 0;
L.length=0;
L.listsize=LIST_INIT_SIZE;
return 1;
}
int list_length(SqList &L)
{
return L.length;
}
int list_insert(SqList &L,int i,ElemType e)
{
ElemType *p;
if(i<1||i>=L.length+1)
return ERROR;
if(L.length >= L.listsize) { // 当前存储空间已满,增加容量
ElemType *newbase = (ElemType *)realloc(L.elem,
(L.listsize + LIST_INCREMENT) * sizeof(ElemType));
if(!newbase)
return ERROR;
// 存储分配失败
L.elem = newbase; // 新基址
L.listsize += LIST_INCREMENT; // 增加存储容量
}
ElemType *q = &(L.elem[i - 1]); // q为插入位置
for(p = &(L.elem[L.length - 1]); p >= q; --p)
{*(p + 1) = *p; } // 插入位置及之后的元素右移
*q = e; // 插入e
L.length++; // 表长增1
return OK;
}
int list_delete(SqList &L,int i,ElemType &e)
{
if(i<1||i>L.length)
return 0;
ElemType *p;
ElemType *q=&L.elem[i-1];
e=*q;
p=&L.elem[L.length -1];
for(q;q<p;q++)
{
*q=*(q+1);
}
L.length--;
return 0;
}
Status DestroyList(SqList &L)
{ // 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L
free(L.elem);
L.elem = NULL;
L.length = 0;
L.listsize = 0;
return OK;
}
void dispList(SqList L)//遍历顺序表
{
for(int i = 1; i <= L.length; i++)
printf("%d ", L.elem[i - 1]);
printf("\n");
}
void swap(ElemType &x, ElemType &y) //交换x和y
{ ElemType tmp=x;
x=y; y=tmp;
}
void SwapMaxMin(SqList &L) //交换L中最大值元素与最小值元素
{ int i,maxi,mini;
maxi=mini=0;
for (i=1;i<L.length;i++)
if (L.elem[i]>L.elem[maxi])
maxi=i;
else if (L.elem[i]<L.elem[mini])
mini=i;
swap(L.elem[maxi],L.elem[mini]);
}
int Deletek(SqList &L,int i,int k)//删除顺序表从I开始的K个元素
{
int j;
if (i<1 || k<1 || i+k-1>L.length)
return 0; //判断i和k是否合法
for (j=i+k-1;j<L.length;j++) //将元素前移k个位置
L.elem[j-k]=L.elem[j];
L.length-=k; //L的长度减k
return 1;
}
void Move(SqList &L)//将所有奇数移到所有的偶数前边
{
int i=0,j=L.length-1;
while (i<j)
{ while (L.elem[i]%2==1) i++; //从前向后找偶数
while (L.elem[j]%2==0) j--; //从后向前找奇数
if (i<j)
swap(L.elem[i],L.elem[j]); //交换这两元素
}
}
void DeleteMinus(SqList &L)//删除其中所有值为负整数的元素
{
int i, k=0;
for (i=0;i<L.length;i++)
if (L.elem[i]>=0) //将不为负数的元素插入到L中
{ L.elem[k]=L.elem[i];
k++;
}
L.length=k; //重置L的长度
}
void reverse(int R[],int m,int n) //将R[m..n]逆置
{ int i;
int tmp;
for (i=0;i<(n-m+1)/2;i++)
{ tmp=R[m+i]; //将R[m+i]与R[n-i]进行交换
R[m+i]=R[n-i];
R[n-i]=tmp;
}
}
int ListReverse(int R[],int n,int p) //循环左移
{ if (p<=0 || p>=n)
return 0;
else
{ reverse(R,0,p-1);
reverse(R,p,n-1);
reverse(R,0,n-1);
return 1;
}
}
Status deleteSame (SqList &L)//删除顺序表中值重复的元素
{
if (L.length == 0) {
printf ("表空,不能删除!\n");
return ERROR;
};
int i, j, k = 0;
for (i = 1; i < L.length; i++) {
for (j = 0; j <= k; j++)
if (L.elem[i] == L.elem[j])
break;
if (j > k && ++k != i)
L.elem[k] = L.elem[i];
}
L.length = k + 1;
return OK;
}
int main ()
{
int n=1,a;
int temp;
SqList P;
list_initialize(P);
int location,number;
//将这个顺序表前十个空间,赋值为0-9,
for(int i=0;i<10;i++){
P.elem[i]=i-5;
printf("%d ",P.elem[i]);
P.length++;
}
printf("\n");
printf("顺序表---菜单---\n");
printf("插入元素请输入:1;\n删除元素请输入:2\n遍历链表请输入:3\n求链表长度输入:4\n销毁链表请输入:5\n");
printf("交换顺序表中最大值元素与最小值元素:6\n删除顺序表从I开始的K个元素 :7\n将所有奇数移到所有的偶数前边:8\n");
printf("删除其中所有值为负整数的元素:9\n循环左移p(0<p<n)个位置:10\n删除顺序表中值重复的元素:11\n");
while(n)
{
printf("请输入要进行的操作数:\n");
scanf("%d",&a);
switch(a)
{
case 1:
printf("输入要插入顺序表的 位置,元素:\n");
scanf("%d %d",&location,&number);
list_insert(P,location,number);
break;
case 2: printf("输入要删除顺序表元素的 位置,保存返回元素用number:\n");
scanf("%d",&location);
list_delete(P,location,number);
break;
case 3: dispList(P);
break;
case 4: printf("目前顺序表长度:");
printf(" %d \n",list_length(P));
break;
case 5: DestroyList(P);
break;
case 6: SwapMaxMin(P);
break;
case 7: printf("输入要删除顺序表第i个元素开始的k个元素-- i k:\n");
scanf("%d %d",&location,&number);
Deletek(P,location,number);
break;
case 8: Move(P);
break;
case 9: DeleteMinus(P);
break;
case 10:printf("需要循环左移p位p:");
scanf("%d",&number);
ListReverse(P.elem,P.length,number);
break;
case 11:deleteSame (P);
break;
}
}
}
单链表算法
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#include<malloc.h>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
// -----结点的c语言描述------
//L List是头结点
typedef struct node{
ElemType data;
struct node *next;
}LNode,*LinkList;
////////////////////////////////////////////
Status InitList_L(LinkList &L)
{
//操作结果:构造一个空的线性表l
//产生头结点,并使L指向此头结点
L=(LinkList)malloc(sizeof(LNode));
if(!L)//存储分配失败
return ERROR;
L->next=NULL;//指针域为空
return OK;
}
//////////////////////////////////////
Status DestroyList(LinkList &L)
{
//
LinkList p;
while(L){
p->next;
free(L);
L=p;
}
return OK;
}
////////////////////////////////////////////////////
int ListLength(LinkList L)
{
//初始化条件:线性表L已经存在。操作结果:返回L中数据元素个数
int i=0;
LinkList p=L->next;//p指向第一个结点
while(p){//没到表尾
i++;
p=p->next;
}
return i;
}
//////////////////////////////////////////
int LocateElem(LinkList L, ElemType e)
{
//操作结果:返回L中的第一个与e相等的数据元素的位序
//若这样的数据元素不存在,则返回值为0
int i=0;
LinkList p=L->next;
while(p)
{
i++;
if(p->data==e)//找到这样的数据元素
return i;
p=p->next;
}
return 0;
}
/////////////////////////////////////////
Status ListInsert_L(LinkList &L,int i,ElemType e)
{
//在带头结点L的单链表的第i个元素之前插入元素e
LinkList p,s;
p=L;
int j=0;
while(p&&j<i-1)
{//寻找第i-1个结点
p=p->next;
++j;
}
if(!p||j>i-1)
{ printf("插入的位置不存在\n");
return ERROR;//i小于1或者大于表长
}
s=(LinkList)malloc(sizeof(LNode));//生成新结点
s->data=e;
s->next=p->next;//插入L中
p->next=s;
return OK;
}
///////////////////////////////////////////
Status ListDelete_L(LinkList &L,int i,ElemType &e)
{
//在带头结点的单链表L中,删除第i个元素,并由e返回其值
LinkList p,q;
p=L;
int j=0;
//寻找第i个结点,并令p指向其前驱
while(p->next&&j<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 ShowAddress(LinkList L)
{
//展示出每个结点的地址
int i;
LinkList p=L->next;
if(p!=NULL)
{
printf("\n头结点的地址为:\t%p\n",L);
for(i=1;p!=NULL;i++)
{
printf("第%d个结点的值为:\t%d;\t地址为 %p\n",i,p->data,p);
p=p->next;
}
}
}
/////////////////////////////////////////////////////////////////
void ShowAddress2(LinkList L)
{
int i;
LinkList p=L->next;
if(p!=NULL)
{
printf("\n头结点的地址为:\t%p\n",L);
printf("头结点->");
for(i=1;p->next !=NULL;i++)
{
printf("%d->",p->data);
p=p->next;
}
printf("%d\n",p->data);
}
}
///////////////////////////////////////////////////////
LNode *MaxNode(LNode *L)
{
//设计一个算法,通过一趟遍历确定单链表L(至少含两个数据结点)中第一个元素值最大的结点。
//返回最大值的地址
//
LNode *p=L->next,*maxp=p;
while(p!=NULL)
{
if(maxp->data<p->data)
maxp=p;
p=p->next;
}
return maxp;
}
//////////////////////////////////////
void DelMaxNode(LNode *&L)
{
//设计一个算法,删除一个单链表L(至少含两个数据结点)中第一个元素值最大的结点。
LNode *p=L->next,*pre=L,*maxp=p,*maxpre=pre;
while (p!=NULL)
{ if (maxp->data<p->data)
{ maxp=p;
maxpre=pre;
}
pre=p; //pre、p同步后移,保证pre始终为p的前驱结点
p=p->next;
}
maxpre->next=maxp->next; //删除maxp结点
free(maxp); //释放maxp结点
}
//////////////////////////////////////////////////////
void ListReverse(LNode *&L)
{
//设计一个算法,将一个单链表L(至少含两个数据结点)中所有结点逆置,并分析算法的时间复杂度。
LinkList p=L->next, q;
L->next=NULL;
while (p!=NULL) //遍历所有数据结点
{ q=p->next; //q临时保存p结点之后的结点
p->next=L->next; //将结点p插入到头结点之后
L->next=p;
p = q;
}
}
//////////////////////////////////////////////
int Searchk(LinkList list,int k)
{
//查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data域的值,并返回1;否则,只返回0
//算法的基本设计思想:定义两个指针变量p和q,初始时均指向头结点的下一个结点。p指针沿链表移动;
//当p指针移动到第k个结点时,q指针开始与p指针同步移动;当p指针移动到链表尾结点时,q指针所指元素为倒数第k个结点。
// 以上过程对链表仅进行一遍扫描。
LinkList p, q;
int count=0;
p=q=list->next;
while (p!=NULL && count<k) //查找第k个结点*p
{ count++;
p=p->next;
}
if (p==NULL)
{printf("第K个元素的数据为 %d \n",q->data); //没有时返回0
return 0;}
else
{ while (p!=NULL) //p和q同步后移直到p=NULL
{ q=q->next;
p=p->next;
}
printf("第K个元素的数据为 %d\n",q->data);
return 1;
}
}
/////////////////////////////////////////////
void splitList(LinkList head, LinkList &headA, LinkList &headB)
{
//下列算法的功能是:设List={a1,b1,a2,b2,......,an,bn}为一线性表,
//采用带头结点的单链表head存放,设计一个就地算法,将其拆分为两个线性表,
//每个线性表均采用带头结点的单链表存储,使得:A={a1,a2,......,an},B={bn,bn-1,......,b2,b1}。
LinkList p = head->next, q, r;
headA = head;
r = headA;
headB = (LNode *)malloc(sizeof(LNode));
headB->next = NULL;
while (p != NULL) {
r->next = p;
r = p;
p = p->next;
q = p->next;
p->next = headB->next;
headB->next = p;
p = q;
}
r->next = NULL;
}
//////////////////////////////////////////////
void List_deletedulicate(LinkList &L)
{
LinkList pre,cur,temp;
pre=L;
cur=L->next;
while(cur!=NULL)
{
if(cur->data ==pre->data )
{temp=cur->next;
free(cur);
cur=temp;
pre->next=temp;}
else
{
pre=pre->next;
cur=cur->next;}
}
}
/////////////////////////////////////////////////////////
void List_deletedulicate2(LinkList &L)
{
//可以使用一个计数器,如果有与当前节点重复的节点,
//删除掉重复节点之后(因为该链表是有序的,所以重复的就是当前节点的下一个),计数器的值加一。
//当前节点重复值删除完之后,判断当前节点是否需要删除就是判断计数器的值是否为0,如果不是0则删除该节点。然后继续遍历
LinkList pre,cur,temp,prepre;
int flag=0;//记录这个元素是否重复出现过吗
prepre=L;
pre=L->next;
cur=pre->next;
while(cur!=NULL)
{
if(cur->data ==pre->data )
{flag=1;
temp=cur->next;
free(cur);
cur=temp;
pre->next=temp;}
else
{if(flag==1)
{
prepre->next=cur;
free(pre);
pre=cur;
cur=cur->next;
}
else
{prepre=prepre->next;
pre=pre->next;
cur=cur->next;}
}
}
}
void List_Bubble(LinkList &L)
{
//冒泡排序
LinkList pre;
LinkList cur;
LinkList next;
int i, j;
i = ListLength(L);
printf("length = %d\n", i);
while(i != 1)//因为当i=1时不需要排序 外层
{
pre = L;
cur = L->next;
next = cur->next;
j = i;
i--;
while(j != 1) //内层
{
j--;
if(cur->data > next->data ) //满足条件则交换
{
cur->next = next->next;
pre->next = next;
next->next = cur;
pre = next;
next = cur->next;
}
else //如果不满足则进行下一步
{
pre = cur;
cur = next;
next = next->next;
}
}
}
}
int main ()
{
int n=1,a;
int temp;
int t,x;
LinkList P;
InitList_L(P);
LinkList help;
InitList_L(help);
int location,number;
printf("---菜单---\n");
printf("[ 1]:插入元素请输入\n[ 2]:删除元素请输入\n[ 3]:遍历链表请输入\n[ 4]:求链表长度输入\n[ 5]:销毁链表请输入\n");
printf("[ 6]:求最大值;\n[ 7]:删除一个单链表L(至少含两个数据结点)中第一个元素值最大的结点\n");
printf("[ 8]:将一个单链表L(至少含两个数据结点)中所有结点逆置(翻转链表)(使用插入法)\n[ 9]:找链表中倒数第k个位置上的结点\n");
printf("[10]:将一个链表拆分为两个线性表\n[11]:删除有序链表的重复元素算法(删除所有的重复元素,使得最终每个元素只出现一次)\n");
printf("[12]:删除有序链表的重复元素算法(删除所有的重复元素,只保留原始链表中 没有重复出现 的数字)\n");
printf("[13]:排序(由小到大的顺序)\n[14]:一次输入n个元素到链表中:\n");
while(n)
{
printf("请输入要进行的操作数:");
scanf("%d",&a);
switch(a)
{
case 1:
printf("输入要插入链表的 位置,元素:\n");
scanf("%d %d",&location,&number);
ListInsert_L(P,location,number);
break;
case 2: printf("输入要删除链表元素的 位置,保存返回元素用number:\n");
scanf("%d",&location);
ListDelete_L(P, location,number);
break;
case 3: printf("1:输入地址,2:链式输出选择(1/2)种遍历算法 x:");
scanf("%d",&x);
if(x==1) ShowAddress(P);
else ShowAddress2(P);
break;
case 4: printf("目前链表长度:");
printf(" %d \n",ListLength(P));
break;
case 5: DestroyList(P);
break;
case 6: *MaxNode(P);
printf("最大元素为%d\n",MaxNode(P)->data );
break;
case 7: DelMaxNode(P);
break;
case 8: ListReverse(P);
break;
case 9: printf("请输入倒数第K的位置 K:");
int k;
scanf("%d",&k);
Searchk(P,k);
break;
case 10:LinkList headA,headB;
splitList(P, headA, headB);
printf("拆分后的两个链表为:\n");
ShowAddress(headA);
ShowAddress(headB);
break;
case 11:List_deletedulicate(P);
ShowAddress(P);
break;
case 12:List_deletedulicate2(P);
ShowAddress2(P);
break;
case 13:List_Bubble(P);
ShowAddress2(P);
break;
case 14:printf("输入n:");
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
printf("即将进入链表的值为:");
scanf("%d",&number);
ListInsert_L(P,i,number);
}
ShowAddress2(P);
break;
}
}
}
780

被折叠的 条评论
为什么被折叠?



