- 利用链表实现可变长数组
在学习C语言中,对利视频课程中,测了测视频中的代码,用C代码实现一个简单的具备增删改查的链表数组,仅供参考。
1、头文件node.h
#ifndef _NODE_H_
#define _NODE_H_
typedef struct _node{
int value;
struct _node *next;
} Node;
#endif
2.主函数main.c
#include "node.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct _list{
Node *head;
} List; // 专门定义了一个Node类型的指针
Node* add(List* pList, int number);
void print(List *pList);
int main()
{
List list; // 定义了变量list,list的成员head存放的是地址变量
int number;
list.head = NULL; // 刚开始链表list的成员head为空
do{
scanf("%d",&number);
if(number !=-1){
list.head = add(&list, number); // add 返回的是Node类型的指针
}
} while(number !=-1);
// print all data in linked-list
print(&list);
// find certain number
printf("input the dta that you want to find:\n");
scanf("%d",&number);
Node *p; // 定义一个Node型指针,便于搜索
int isFound = 0;
for (p=list.head; p; p=p->next){
if( p->value == number){
printf("find:%d\n",number);
isFound = 1;
break;
}
}
if(!isFound){
printf("no found\n");
}
// delete certain number
printf("input the dta that you want to delete:\n");
scanf("%d",&number);
Node *q;
// q is ahead,p is next
for (q= NULL, p=list.head; p; q=p,p=p->next){
if( p->value == number){
if(q){
printf("find:%d,and delete it\n",number);
q->next = p->next;
}else{
list.head = p->next; // when q is fist one
}
free(p->next);
break;
}
}
// delete all linked-list
printf("delete all data\n");
for(p=list.head; p; p=q){
q = p->next;
free(p);
}
return 0;
}
// add the data to linked-list
Node* add(List* pList, int number)
{
// add to lined-list 创建一个Node类型的内存空间,并存上数 ,形成一个节点
Node *p = (Node*)malloc(sizeof(Node));
p->value = number;
p->next = NULL;
// find the last
Node *last = pList->head; // 定义了一个 Node 型指针 ,专门用来存最后一个节点的地址
if(last){
while (last->next){ // 第一次满足if条件时,while不满足
last = last->next; // 3、更新last指向,last指向最新一个节点,所以是上一节点的next
}
last->next = p; // 2、刚形成那一个节点的地址赋给最后一节点存地址的next
} else{
pList->head = p; // 1、如果是第一个 ,直接把刚形成的那一节点的地址赋给头地址
}
return pList->head;
}
// output all data in the linked-list
void print(List *pList)
{
Node *p;
for (p=pList->head; p; p = p->next) {
printf("%d\t",p->value);
}
printf("\n");
}
- 利用新建内存空间的方式形成可变长数组
#include <iostream>
using namespace std;
class CArray{
private:
int size; //数组元素的个数
int *ptr; // 指向动态分配的数组
public:
CArray(int s=0); // s代表数组元素个数,构造函数
CArray(CArray & a); // 赋值构造函数
~CArray(); // 析构函数
void push_back(int i); // 具体的需求函数
CArray & operator=(const CArray & a); // 赋值号重载函数,用于数组对象间的赋值
int length() // 返回数组元素的个数
{
return size;
}
int & operator[](int i) //重载[]
{// 用于支持根据下表访问数组元素,如 n = a[1]; a[2] = 4;
return ptr[i];
}
};
CArray::CArray(int s):size(s) // 构造函数
{
if(s == 0) {
ptr = NULL;
}
else
ptr = new int[s]; // 动态分配内存空间
}
CArray::CArray(CArray &a){ // 复制构造函数
if(!a.ptr){
ptr = NULL;
size = 0;
return;
}
ptr = new int[a.size];
memcpy(ptr, a.ptr, sizeof(int)*a.size);
size = a.size;
}
CArray::~CArray(){
if(ptr) delete []ptr;
}
CArray & CArray::operator=(const CArray &a){
if(ptr == a.ptr) // 防止a=a赋值的错误
return *this;
if(a.ptr == NULL){
if(ptr) delete [] ptr;
ptr = NULL;
size = 0;
return *this;
}
if(size < a.size){
if(ptr)
delete [] ptr;
ptr = new int[a.size];
}
memcpy(ptr, a.ptr, sizeof (int)*a.size);
size=a.size;
return *this;
}
void CArray::push_back(int v)
{// 在数组尾部增加元素
if(ptr){
int *tmpPtr = new int[size + 1]; //重新分配内存空间
memcpy(tmpPtr,ptr,sizeof (int)*size); //copy原数据
delete []ptr;
ptr = tmpPtr;
}
else {
ptr = new int[1];
}
ptr[size++]=v; // 加入新的数组元素
}
int main()
{
CArray a;
for(int i = 0; i<5; i++)
a.push_back(i); // 动态分配内存空间来存放数组变量
CArray a2, a3;
a2 = a; // 赋值号需要重构
for(int i=0; i<a.length(); ++i)
cout<<a2[i]<<" "; // 对象[] 是重构了[]
cout<<endl;
a[3] = 100;
CArray a4(a);
for(int i=0; i<a4.length(); i++)
cout<<a4[i]<<" ";
return 0;
}